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

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

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

問題描述

限時送ChatGPT賬號..

我想將 MM-dd 格式的字符串解析為 java 日期.由于未指定年份,因此解析日期應為當年.應該只解析有效的日期字符串,所以我應該在 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();}

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

我發現當我在SimpleDateFormat中不指定年份部分時,它會解析到1970年.而1970年不是閏年,02-29"無法解析.因此,解析到 1970 年的日期并在解析后設置當前年份的策略并不完美.

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

PS1:我搜索了這個話題,在本站找到了很多問題和答案,但都沒有找到滿意的答案.PS2:df.setLenient(false); 很重要,因為只有有效的日期字符串才能成功解析.不應解析01-32"、02-30"等無效日期字符串.

提前致謝.

解決方案

tl;dr

<塊引用>

以 MM-dd 格式解析字符串……在當年

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

查看此在 IdeOne.com 上運行的代碼.

<塊引用>

2019-02-28

java.time

現代解決方案使用 Java 8 及更高版本中內置的行業領先的 java.time 類,并具有適用于 Java 6 和更高版本的后端端口.7 和早期的 Android.

月日

月份與日期由適當命名的 MonthDay 類.

ISO 8601 中定義的月日標準格式是 --MM-DD,其中第一個破折號是年份的占位符.java.time 類中默認使用 ISO 8601 格式來解析/生成字符串.

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

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

然后默認解析.

MonthDay md = MonthDay.parse(inputModified);

查看此在 IdeOne.com 上運行的代碼.

<塊引用>

md.toString(): --02-29

閏年

請注意,您的閏年問題消失了.通過使用真正代表月份和日期而不是時刻的適當類型,我們不必擔心閏年.

要獲取本月的日期,只需調用 MonthDay::atYear 獲取 LocalDate 對象.通過年號.

LocalDate jumpYear2012 = md.atYear(2012);

<塊引用>

leapYear2012.toString(): 2012-02-29

當年

在當年獲得一個日期可能會讓您感到驚訝.請注意,獲取當前年份需要獲取當前日期.獲取當前日期需要時區.

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

如果沒有指定時區,JVM 會隱式應用其當前的默認時區.該默認值可能 在運行時(!)期間隨時更改,因此您的結果可能會有所不同.最好將您想要/預期的時區明確指定為參數.如果您想使用 JVM 當前的默認時區,請通過調用 ZoneId.systemDefault() 明確您的意圖.如果關鍵,請與您的用戶確認該區域.

大陸/地區,例如 America/MontrealAfrica/Cas??ablancaPacific/Auckland.切勿使用 2-4 字母縮寫,例如 ESTIST,因為它們不是真正的時區,沒有標準化,甚至不是唯一的(!).

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

在我們的例子中,我們只關心年份.所以我們可以使用 Year 類而不是 LocalDate.但與時區相同的想法.如果當前時刻恰好是在新年前夜/新年前夜切換,那么全球各地的年份會因時區而異.

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

<塊引用>

currentYear.toString(): 2019-02-28

請注意,上述結果中的閏年是自動處理的.2019年沒有2月29日,所以java.time調整為28日.

解析為 LocalDate

或者,您可以直接解析為 LocalDate.您需要使用 DateTimeFormatterBuilder 類來構建默認為特定年份的 DateTimeFormatter.

類似這樣的:

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 對象的方法對于您的問題、解決方案和意圖更加清晰.另一個好處:如果你得到這樣的輸入,我懷疑你可能需要像這樣處理月日,并且使用 MonthDay 類你手頭有一個對象來完成這項工作.

<小時>

關于java.time

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

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

Joda-Time 項目,現在在 維護模式,建議遷移到 java.time 類.

您可以直接與您的數據庫交換 java.time 對象.使用符合 JDBC 驅動程序/jeps/170" rel="nofollow noreferrer">JDBC 4.2 或更高版本.不需要字符串,不需要 java.sql.* 類.

從哪里獲得 java.time 類?

  • Java SE 8Java SE 9, Java SE 10, Java SE 11 及更高版本 - 具有捆綁實現的標準 Java API 的一部分.
    • Java 9 添加了一些小功能和修復.
  • Java SE 6Java SE 7
    • 大部分 java.time 功能都向后移植到 Java 6 &7 在 ThreeTen-Backport.
  • Android
    • java.time 類的 Android 捆綁包實現的更高版本.
    • 對于早期的 Android (<26),ThreeTenABP 項目改編 ThreeTen-Backport(如上所述).請參閱如何使用 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….

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

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

相關文檔推薦

Parsing an ISO 8601 string local date-time as if in UTC(解析 ISO 8601 字符串本地日期時間,就像在 UTC 中一樣)
How to convert Gregorian string to Gregorian Calendar?(如何將公歷字符串轉換為公歷?)
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 日之前日期的日歷到日期轉換.公歷到儒略歷切換)
java Calendar setFirstDayOfWeek not working(java日歷setFirstDayOfWeek不起作用)
Java: getting current Day of the Week value(Java:獲取當前星期幾的值)
主站蜘蛛池模板: 国产一区二区在线视频 | 日韩免费一区二区 | 精品欧美一区二区三区精品久久 | 国产精品色av | 久久亚洲一区 | 国产精品中文字幕在线播放 | 久久不卡区| 亚洲网在线 | 欧美在线综合 | 国产不卡一区 | 羞羞视频网页 | 亚洲精品18 | 黄片毛片免费观看 | 狠狠天天 | 在线国产小视频 | 国精产品一区二区三区 | 国产剧情一区 | 国产成人精品免费视频大全最热 | 91精品国产综合久久久久久蜜臀 | 中文字幕精| 亚欧洲精品在线视频免费观看 | 国产成人jvid在线播放 | 国产一级片在线播放 | 日韩有码在线观看 | 亚洲综合色视频在线观看 | 成人av一区 | www.毛片| 91久久| 国产资源在线播放 | 天天操天天摸天天干 | 狠狠干影院 | 国产精品久久久久久婷婷天堂 | 中文字幕高清av | 久久久青草婷婷精品综合日韩 | av中文字幕在线播放 | 亚洲免费在线观看视频 | 精品无码久久久久久国产 | 精品久久99| 亚洲永久免费观看 | 天天夜夜操 | 欧美区在线观看 |