我想将MM-dd格式的字符串解析为java
date。由于未指定年份,因此解析日期应为当前年份。只能解析有效的日期字符串,因此我应该setLenient(false)
在中使用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();
}
在我传递参数“ 02-29”之前,这似乎工作得很好。今年(2012)是leap年,2012-02-29是有效日期,应该成功解析“ 02-29”。
我发现当我未在中指定年份部分时SimpleDateFormat
,它将分析为1970年。而1970年不是a年,则“
02-29”将无法分析。因此,解析日期到1970年并在解析策略后设置当前年份并不完美。
用Java解析MM-dd格式的字符串到日期(日期应设置为当年)的最佳方法是什么?
PS1:我搜索了此主题,并在此站点中找到了许多问题和答案,但找不到满意的答案。PS2:df.setLenient(false);
之所以重要,是因为只有有效的日期字符串才能成功解析。不应解析无效的日期字符串,例如“
01-32”,“ 02-30”等。
提前致谢。
在当年解析MM-dd格式的字符串…
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.
看到此代码在IdeOne.com上实时运行。
2019-02-28
现代解决方案使用Java 8及更高版本内置的行业领先的 java.time 类,并为Java 6&7和早期Android提供了反向端口。
MonthDay
每天的一个月由适当命名的MonthDay
类表示。
ISO 8601中定义的月日标准格式是--MM-DD
第一个破折号代表年份的占位符。缺省情况下, java.time 类中使用ISO
8601格式来解析/生成字符串。
您的输入几乎符合要求。您可以使用DateTimeFormatter
对象定义格式设置模式。但是我只是将a --
放在输入之前。
String input = "02-29" ;
String inputModified = "--" + input ;
然后默认解析。
MonthDay md = MonthDay.parse( inputModified ) ;
看到此代码在IdeOne.com上实时运行。
md.toString():–02-29
请注意,您的leap年问题就消失了。通过使用真正代表一个月而不是一瞬间的适当类型,我们不必担心leap年。
要获取该月日的日期,只需调用MonthDay::atYear
即可获取一个LocalDate
对象。通过一年数。
LocalDate leapYear2012 = md.atYear( 2012 ) ;
jumpYear2012.toString():2012-02-29
获取当前年份的日期可能会让您感到意外。请注意,获取当前年份需要获取当前日期。获取 当前日期需要一个时区 。
时区对于确定日期至关重要。在任何给定时刻,日期都会在全球范围内变化。例如,法国巴黎午夜过后的几分钟是新的一天,而在魁北克蒙特利尔仍然是“昨天”
。
如果未指定时区,则JVM隐式应用其当前的默认时区。该默认值可能会在运行时(!)期间随时更改,因此您的结果可能会有所不同。最好将您的期望/期望时区明确指定为参数。如果要使用JVM的当前默认时区,请通过调用明确意图ZoneId.systemDefault()
。如果紧急,请与您的用户确认区域。
指定适当的时区名称,格式Continent/Region
,如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用2-4字母的缩写,例如EST
或,IST
因为它们
不是 真实的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
就我们而言,我们只关心年份。因此,我们可以使用Year
类而不是LocalDate
。但是对于时区也是如此。如果当前时刻恰好是除夕/日切换,那么该年份将在全球各地按时区变化。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
Year y = Year.now( z ) ;
LocalDate currentYear = md.atYear( y.getValue() ) ;
currentYear.toString():2019-02-28
请注意,以上结果将自动处理leap年。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
8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.Date
,Calendar
,和SimpleDateFormat
。
要了解更多信息,请参见
Oracle教程 。并在Stack
Overflow中搜索许多示例和说明。规格为JSR 310。
现在处于维护模式的 Joda-
Time
项目建议迁移到java.time类。
您可以直接与数据库交换 java.time 对象。使用与JDBC
4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要类。java.sql.*
在哪里获取java.time类?
当我将格式的字符串对象转换为时,它会给我 我试着这样做:
问题内容: 当我将格式的字符串对象转换为它给我时 我正在尝试这样做: 问题答案: 这里有几个潜在的问题: 您未指定格式 您未指定语言环境 您未指定时区 您正在尝试将返回值(将是引用)转换为-,否则将失败 您想要类似:
问题内容: 我正在尝试使用以下方式将dd-mm-yyyy格式的字符串转换为JavaScript中的日期对象: 包含格式为dd-mm-yyyy的日期。当我执行以下操作时,我得到“无效日期”: 这是因为符号“-”吗?我该如何克服? 问题答案: 分割为“-” 将字符串解析为所需的部分: 使用正则表达式 为什么不使用正则表达式? 因为您知道将要使用由连字符分隔的三部分组成的字符串。 但是,如果您要在另一个
问题内容: 我想在Java中解析这种格式为dd / MM / yyyy [至dd / MM / yyyy]的String的最佳方法是什么。带[]的字符串是可选的,dd代表日期的2位数字表示,MM是月份的2位数字表示,yyyy是年份的4位数字表示。 更新资料 谢谢大家的快速响应,但是我忘了告诉您[]是象征可选的,字符串中没有[]示例字符串可能是 22/01/2010 从22/01/2010至23/0
问题内容: 我有多个具有生日的联系人,并且所有联系人都已与移动设备同步。现在的问题是所有联系人的生日格式都不同,我想以“ dd-MM- yyyy”之类的特定格式显示所有生日日期。 因此,例如,一个同步联系人的生日为“ 1990-02-07”或“ 1988-06-15T22:00:00.000Z”或“ 12-02-1990”等,则应显示所有这些日期以特定格式“ dd-MM-yyyy”。 那我该如何解
我有多个联系人的出生日期,并且都与移动设备同步。现在的问题是所有联系人都有不同的生日格式,我想以特定格式显示所有生日日期,例如“dd-MM-yyyy”。 例如,一个同步联系人的生日是“1990-02-07”或“1988-06-15T22:00:00.000Z”或“12-02-1990”等...那么所有这些日期都应该以特定的格式“dd-MM-yyyy”显示。 那么我该如何解决这个问题呢? 如有任何建