久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

將日期字符串(MM-dd)解析為默認(rèn)年份的 java 日期

Parsing date string (MM-dd) to java date in default year(將日期字符串(MM-dd)解析為默認(rèn)年份的 java 日期)
本文介紹了將日期字符串(MM-dd)解析為默認(rèn)年份的 java 日期的處理方法,對(duì)大家解決問(wèn)題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧!

問(wèn)題描述

限時(shí)送ChatGPT賬號(hào)..

我想將 MM-dd 格式的字符串解析為 java 日期.由于未指定年份,因此解析日期應(yīng)為當(dāng)年.應(yīng)該只解析有效的日期字符串,所以我應(yīng)該在 SimpleDateFormat 中使用 setLenient(false).

public static Date parseDate(String ds) throws ParseException {SimpleDateFormat df = new SimpleDateFormat("MM-dd");df.setLenient(false);日期 d = df.parse(ds);日歷 cal = Calendar.getInstance();int year = cal.get(Calendar.YEAR);cal.setTime(d);cal.set(Calendar.YEAR, 年);返回 cal.getTime();}

在我通過(guò)參數(shù)02-29"之前,這似乎運(yùn)作良好.今年(2012)是閏年,2012-02-29是有效日期,02-29"應(yīng)該已經(jīng)解析成功了.

我發(fā)現(xiàn)當(dāng)我在SimpleDateFormat中不指定年份部分時(shí),它會(huì)解析到1970年.而1970年不是閏年,02-29"無(wú)法解析.因此,解析到 1970 年的日期并在解析后設(shè)置當(dāng)前年份的策略并不完美.

在 Java 中解析 MM-dd 格式字符串到日期(日期應(yīng)設(shè)置為當(dāng)前年份)的最佳方法是什么?

PS1:我搜索了這個(gè)話(huà)題,在本站找到了很多問(wèn)題和答案,但都沒(méi)有找到滿(mǎn)意的答案.PS2:df.setLenient(false); 很重要,因?yàn)橹挥杏行У娜掌谧址拍艹晒馕?不應(yīng)解析01-32"、02-30"等無(wú)效日期字符串.

提前致謝.

解決方案

tl;dr

<塊引用>

以 MM-dd 格式解析字符串……在當(dāng)年

MonthDay//在為此目的設(shè)計(jì)的類(lèi)中表示一個(gè)月的一天..parse (//默認(rèn)情況下以標(biāo)準(zhǔn) ISO 8601 格式解析字符串."--" + "02-29"http://在前面加上雙連字符以使此輸入符合 ISO 8601.)//返回一個(gè) `MonthDay` 對(duì)象..atYear(//獲取指定年份本月日的日期.Year.now( ZoneId.of( "Asia/Tokyo" ) ).getValue()//獲取當(dāng)前年份需要時(shí)區(qū).)//返回一個(gè) `LocalDate` 對(duì)象,一個(gè)沒(méi)有時(shí)區(qū)和沒(méi)有時(shí)間的年月日.

查看此在 IdeOne.com 上運(yùn)行的代碼.

<塊引用>

2019-02-28

java.time

現(xiàn)代解決方案使用 Java 8 及更高版本中內(nèi)置的行業(yè)領(lǐng)先的 java.time 類(lèi),并具有適用于 Java 6 和更高版本的后端端口.7 和早期的 Android.

月日

月份與日期由適當(dāng)命名的 MonthDay 類(lèi).

ISO 8601 中定義的月日標(biāo)準(zhǔn)格式是 --MM-DD,其中第一個(gè)破折號(hào)是年份的占位符.java.time 類(lèi)中默認(rèn)使用 ISO 8601 格式來(lái)解析/生成字符串.

您的輸入幾乎符合要求.您可以使用 DateTimeFormatter 對(duì)象定義格式模式.但我只會(huì)在輸入前添加一個(gè) --.

字符串輸入=02-29";字符串 inputModified = "--" + 輸入;

然后默認(rèn)解析.

MonthDay md = MonthDay.parse(inputModified);

查看此在 IdeOne.com 上運(yùn)行的代碼.

<塊引用>

md.toString(): --02-29

閏年

請(qǐng)注意,您的閏年問(wèn)題消失了.通過(guò)使用真正代表月份和日期而不是時(shí)刻的適當(dāng)類(lèi)型,我們不必?fù)?dān)心閏年.

要獲取本月的日期,只需調(diào)用 MonthDay::atYear 獲取 LocalDate 對(duì)象.通過(guò)年號(hào).

LocalDate jumpYear2012 = md.atYear(2012);

<塊引用>

leapYear2012.toString(): 2012-02-29

當(dāng)年

在當(dāng)年獲得一個(gè)日期可能會(huì)讓您感到驚訝.請(qǐng)注意,獲取當(dāng)前年份需要獲取當(dāng)前日期.獲取當(dāng)前日期需要時(shí)區(qū).

時(shí)區(qū)對(duì)于確定日期至關(guān)重要.對(duì)于任何給定的時(shí)刻,日期在全球范圍內(nèi)因區(qū)域而異.例如,在 Paris France 午夜過(guò)后幾分鐘是新的一天,但仍然昨天"在 蒙特利爾魁北克.

如果沒(méi)有指定時(shí)區(qū),JVM 會(huì)隱式應(yīng)用其當(dāng)前的默認(rèn)時(shí)區(qū).該默認(rèn)值可能 在運(yùn)行時(shí)(!)期間隨時(shí)更改,因此您的結(jié)果可能會(huì)有所不同.最好將您想要/預(yù)期的時(shí)區(qū)明確指定為參數(shù).如果您想使用 JVM 當(dāng)前的默認(rèn)時(shí)區(qū),請(qǐng)通過(guò)調(diào)用 ZoneId.systemDefault() 明確您的意圖.如果關(guān)鍵,請(qǐng)與您的用戶(hù)確認(rèn)該區(qū)域.

大陸/地區(qū),例如 America/MontrealAfrica/Cas??ablancaPacific/Auckland.切勿使用 2-4 字母縮寫(xiě),例如 ESTIST,因?yàn)樗鼈?em>不是真正的時(shí)區(qū),沒(méi)有標(biāo)準(zhǔn)化,甚至不是唯一的(!).

ZoneId z = ZoneId.of("美國(guó)/蒙特利爾");今天的 LocalDate = LocalDate.now( z ) ;

在我們的例子中,我們只關(guān)心年份.所以我們可以使用 Year 類(lèi)而不是 LocalDate.但與時(shí)區(qū)相同的想法.如果當(dāng)前時(shí)刻恰好是在新年前夜/新年前夜切換,那么全球各地的年份會(huì)因時(shí)區(qū)而異.

ZoneId z = ZoneId.of("非洲/突尼斯");年份 y = Year.now( z ) ;LocalDate currentYear = md.atYear( y.getValue() ) ;

<塊引用>

currentYear.toString(): 2019-02-28

請(qǐng)注意,上述結(jié)果中的閏年是自動(dòng)處理的.2019年沒(méi)有2月29日,所以java.time調(diào)整為28日.

解析為 LocalDate

或者,您可以直接解析為 LocalDate.您需要使用 DateTimeFormatterBuilder 類(lèi)來(lái)構(gòu)建默認(rèn)為特定年份的 DateTimeFormatter.

類(lèi)似這樣的:

ZoneId zKolkata = ZoneId.of("Asia/Kolkata") ;long yearNumber = Year.now(zKolkata).getValue();DateTimeFormatter formatter = new DateTimeFormatterBuilder().parseDefaulting( ChronoField.YEAR , yearNumber ).appendPattern( "MM-dd").toFormatter() ;LocalDate ld = LocalDate.parse("02-28" , formatter ) ;System.out.println("ld.toString():" + ld);

但我不建議這樣做.MonthDay 對(duì)象的方法對(duì)于您的問(wèn)題、解決方案和意圖更加清晰.另一個(gè)好處:如果你得到這樣的輸入,我懷疑你可能需要像這樣處理月日,并且使用 MonthDay 類(lèi)你手頭有一個(gè)對(duì)象來(lái)完成這項(xiàng)工作.

<小時(shí)>

關(guān)于java.time

java.time 框架內(nèi)置于 Java 8 及更高版本中.這些類(lèi)取代了麻煩的舊 legacy 日期時(shí)間類(lèi),例如 java.util.Date, 日歷, &SimpleDateFormat.

要了解更多信息,請(qǐng)參閱 Oracle 教程.并在 Stack Overflow 上搜索許多示例和解釋.規(guī)范是 JSR 310.

Joda-Time 項(xiàng)目,現(xiàn)在在 維護(hù)模式,建議遷移到 java.time 類(lèi).

您可以直接與您的數(shù)據(jù)庫(kù)交換 java.time 對(duì)象.使用符合 JDBC 驅(qū)動(dòng)程序/jeps/170" rel="nofollow noreferrer">JDBC 4.2 或更高版本.不需要字符串,不需要 java.sql.* 類(lèi).

從哪里獲得 java.time 類(lèi)?

  • Java SE 8Java SE 9, Java SE 10, Java SE 11 及更高版本 - 具有捆綁實(shí)現(xiàn)的標(biāo)準(zhǔn) Java API 的一部分.
    • Java 9 添加了一些小功能和修復(fù).
  • Java SE 6Java SE 7
    • 大部分 java.time 功能都向后移植到 Java 6 &7 在 ThreeTen-Backport.
  • Android
    • java.time 類(lèi)的 Android 捆綁包實(shí)現(xiàn)的更高版本.
    • 對(duì)于早期的 Android (<26),ThreeTenABP 項(xiàng)目改編 ThreeTen-Backport(如上所述).請(qǐng)參閱如何使用 ThreeTenABP….

I'd like to parse string in MM-dd format to java date. Since year is not specified, parsed date should be in current year. Only valid date string should be parsed, so I should use setLenient(false) in SimpleDateFormat.

public static Date parseDate(String ds) throws ParseException {
    SimpleDateFormat df = new SimpleDateFormat("MM-dd");
    df.setLenient(false);
    Date d = df.parse(ds);
    Calendar cal = Calendar.getInstance();
    int year = cal.get(Calendar.YEAR);
    cal.setTime(d);
    cal.set(Calendar.YEAR, year);
    return cal.getTime();
}

This seems to work well until I pass an argument "02-29". This year(2012) is leap year and 2012-02-29 is valid date, "02-29" should have been parsed successfully.

I found that when I don't specify year part in SimpleDateFormat, it parse to year 1970. And 1970 is not a leap year, "02-29" fails to parse. So, parsing to date of year 1970 and set current year after parsing strategy is not perfect.

What is the best way to parse MM-dd format string to date (date should be set to current year) in Java?

PS1: I searched this topic and found many questions and answers in this site, but I couldn't find the satisfactory answer. PS2: df.setLenient(false); is important because only valid date string should be parsed successfully. Invalid date strings like "01-32", "02-30", etc. shouldn't be parsed.

Thanks in advance.

解決方案

tl;dr

parse string in MM-dd format … in current year

MonthDay               // Represent a month-day as such, in a class designed for that purpose.
.parse (               // By default parses strings in standard ISO 8601 format.
    "--" + "02-29"     // Prepending a double-hyphen to make this input comply with ISO 8601.
)                      // Returns a `MonthDay` object.
.atYear(               // Get the date of this month-day in a specified year.
    Year.now( ZoneId.of( "Asia/Tokyo" ) ).getValue()  // Getting current year requires a time zone.
)                      // Returns a `LocalDate` object, a year-month-day without time zone and without time-of-day. 

See this code run live at IdeOne.com.

2019-02-28

java.time

The modern solution uses the industry-leading java.time classes built into Java 8 and later, with a back-port available for Java 6 & 7 and early Android.

MonthDay

A month-with-day is represented by the appropriately-named MonthDay class.

The standard format for a month-day defined in ISO 8601 is a --MM-DD where the first dash is a placeholder for year. The ISO 8601 formats are used by default in the java.time classes for parsing/generating strings.

Your input nearly complies. You could define a formatting pattern with a DateTimeFormatter object. But I would just prepend a -- onto the input.

String input = "02-29" ;
String inputModified = "--" + input ;

And then parse by default.

MonthDay md = MonthDay.parse( inputModified ) ;

See this code run live at IdeOne.com.

md.toString(): --02-29

Leap year

Note that your leap year problem goes away. By use an appropriate type that truly represents a month-and-day instead of a moment, we need not worry about leap year.

To get a date for this month-day, simply call MonthDay::atYear to obtain a LocalDate object. Pass a year number.

LocalDate leapYear2012 = md.atYear( 2012 ) ;

leapYear2012.toString(): 2012-02-29

Current year

Getting a date in the current year has a twist that may be surprising to you. Note that getting the current year requires getting the current date. And getting the current date requires a time zone.

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still "yesterday" in Montréal Québec.

If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument. If you want to use the JVM’s current default time zone, make your intention clear by calling ZoneId.systemDefault(). If critical, confirm the zone with your user.

Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

In our case, we care only about the year. So we can use the Year class rather than LocalDate. But same idea with the time zone. If the current moment happens to be around New Years Eve/Day cutover, the year will vary around the globe by time zone.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
Year y = Year.now( z ) ;
LocalDate currentYear = md.atYear( y.getValue() ) ;

currentYear.toString(): 2019-02-28

Notice in the result above that leap year is handled automatically. There is no February 29th in 2019, so java.time adjusted to the 28th.

Parse as LocalDate

Alternatively, you could parse directly into a LocalDate. You would need to use the DateTimeFormatterBuilder class to build a DateTimeFormatter that defaults to a certain year.

Something like this:

ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" ) ;
long yearNumber = Year.now( zKolkata ).getValue() ;
DateTimeFormatter formatter = new DateTimeFormatterBuilder().parseDefaulting( ChronoField.YEAR , yearNumber ).appendPattern( "MM-dd").toFormatter() ;
LocalDate ld = LocalDate.parse( "02-28" , formatter ) ;
System.out.println( "ld.toString(): " + ld ) ;

But I do not recommend this. The approach with MonthDay object is much more clear as to your problem, solution, and intention. Another benefit: if you are getting such inputs, I suspect you will likely need to be working with the month-day as such, and with MonthDay class you have an object at hand to do the job.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

  • Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and Java SE 7
    • Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • Later versions of Android bundle implementations of the java.time classes.
    • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

這篇關(guān)于將日期字符串(MM-dd)解析為默認(rèn)年份的 java 日期的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!

【網(wǎng)站聲明】本站部分內(nèi)容來(lái)源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問(wèn)題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請(qǐng)聯(lián)系我們刪除處理,感謝您的支持!

相關(guān)文檔推薦

Parsing an ISO 8601 string local date-time as if in UTC(解析 ISO 8601 字符串本地日期時(shí)間,就像在 UTC 中一樣)
How to convert Gregorian string to Gregorian Calendar?(如何將公歷字符串轉(zhuǎn)換為公歷?)
Java: What/where are the maximum and minimum values of a GregorianCalendar?(Java:GregorianCalendar 的最大值和最小值是什么/在哪里?)
Calendar to Date conversion for dates before 15 Oct 1582. Gregorian to Julian calendar switch(1582 年 10 月 15 日之前日期的日歷到日期轉(zhuǎn)換.公歷到儒略歷切換)
java Calendar setFirstDayOfWeek not working(java日歷setFirstDayOfWeek不起作用)
Java: getting current Day of the Week value(Java:獲取當(dāng)前星期幾的值)
主站蜘蛛池模板: 亚洲欧美久久 | 日韩中文av在线 | 天天看天天操 | 91精品国产欧美一区二区成人 | 亚洲福利一区二区 | 久久毛片网站 | 综合久久99 | 久久国产欧美一区二区三区精品 | 精品国产一区二区在线 | 成人精品久久日伦片大全免费 | www.日韩 | 国产亚洲一区二区三区在线观看 | 久久久精品综合 | www亚洲成人 | 欧洲av一区 | 精品亚洲一区二区三区 | 国内精品久久久久久影视8 最新黄色在线观看 | 日本欧美视频 | 精品久久久久久亚洲精品 | 亚洲天堂一区二区 | 91在线视频免费观看 | 精品久久久久久久 | 亚洲国产精品激情在线观看 | 亚洲欧美在线视频 | 天堂在线91| 日韩国产欧美在线观看 | 亚洲伊人久久综合 | 国产乱码精品一品二品 | 免费视频99 | 国产日韩精品一区 | 综合久久久久久久 | 高清一区二区三区 | 精品二区 | 99热在线播放| 中文字幕av在线一二三区 | 毛片毛片毛片毛片毛片 | 亚洲欧美日韩久久久 | 国产日韩精品在线 | 婷婷毛片 | 99久久久无码国产精品 | 一区二区在线看 |