Dav*_*gan 20 java simpledateformat
这开始作为一个简单的错误:我有YYYY,而不是yyyy在我的格式字符串的SimpleDateFormat对象.但是我对使用不正确格式字符串的测试结果感到困惑.
这段代码:
@Test
public void whatTheHell() {
try {
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/YYYY");
Date d1 = sdf.parse("01/07/2016");
Date d2 = sdf.parse("02/08/2016");
Date d3 = sdf.parse("11/29/2027");
System.out.println(d1.toString());
System.out.println(d2.toString());
System.out.println(d3.toString());
} catch (ParseException pe) {
fail("ParseException: " + pe.getMessage());
}
}
Run Code Online (Sandbox Code Playgroud)
产生这个输出:
Sun Dec 27 00:00:00 PST 2015
Sun Dec 27 00:00:00 PST 2015
Sun Dec 27 00:00:00 PST 2026
Run Code Online (Sandbox Code Playgroud)
我在这里阅读了关于'Y'参数的文档:https://docs.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html,但我仍然看不到它的逻辑在这里工作.特别是最后一个例子:我可以有点理解1月(也可能是2月)的日期如何转化为上一年的12月,但将11月29日的日期向后移动11个月让我感到困惑.12月27日有什么特别之处?
谁能解释一下?
更多信息
@Jan建议依赖toString()方法可能是个问题,所以我定义了一个日期格式,以YYYY MM dd '-' yyyy MM dd与上面相同的代码进行打印.这是额外的输出:
2016 12 27 - 2015 12 27
2016 12 27 - 2015 12 27
2027 12 27 - 2026 12 27
Run Code Online (Sandbox Code Playgroud)
这很简单:2015年12月27日是2016年第1周第1天(2026年12月27日是2027年第1周第1天).这可以通过添加以下行来验证:
SimpleDateFormat odf = new SimpleDateFormat("YYYY-ww-u");
System.out.println(odf.format(d1));
System.out.println(odf.format(d2));
System.out.println(odf.format(d3));
Run Code Online (Sandbox Code Playgroud)
如果SimpleDateFormat输出日期,则可以使用所有字段:年,月,日,星期几,星期几,星期,星期等.
在解析时,SimpleDateFormat需要一组匹配的值:日,月,年或星期几,星期,星期和星期.由于您提供的是一周,但没有提供一周中的一周和一周中的一周,因此将这些值假设为1.
实际值取决于您的区域设置:
(参见https://docs.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html#week_and_year)
在我的系统上(使用de-ch语言环境,以"EEE MMM dd HH:mm:ss zzz yyyy - YYYY-ww-u"作为格式)我得到
Mo Jan 04 00:00:00 MEZ 2016 - 2016-01-1 Mo Jan 04 00:00:00 MEZ 2016 - 2016-01-1 Mo Jan 04 00:00:00 MEZ 2027 - 2027-01-1
可以用不同的方式定义一周。例如,在美国,一周的第一天通常被认为是星期日,而在欧洲和许多其他地方,第一天是星期一。
同样,也可以以不同的方式定义基于一周的一年中的一周。
您正在使用的旧类隐式使用所指定的定义Locale。Locale如果未另行指定,则使用JVM的当前缺省值,所应用的语言环境也是隐式的。
有关难以定义星期的更多有趣的详细信息,请参阅此问题,JVM 8和JVM 10上WeekFields的不同行为
对于日期时间处理,有一个实用的国际标准ISO 8601。
一周的ISO 8601定义是:
我建议尽可能使用ISO 8601标准定义。该标准定义既简单又合乎逻辑,并且在整个行业中得到越来越多的采用。
该java.time类提供的基于周的星期一定的支持WeekFields类。
LocalDate ld = LocalDate.of( 2019 , Month.JANUARY , 1 ) ;
long week = ld.get( WeekFields.ISO.weekOfWeekBasedYear() ) ;
Run Code Online (Sandbox Code Playgroud)
参见IdeOne.com实时运行此代码。
ld.toString():2019-01-01
周:1
org.threeten.extra.YearWeek但是,如果要做很多工作,我建议将ThreeTen-Extra库添加到您的项目中。您会发现该YearWeek课程对您有所帮助。此类提供了几种便捷的方法,例如LocalDate在该周的任何一天生成一个。
LocalDate ld = LocalDate.of ( 2019 , Month.JANUARY , 1 );
YearWeek yw = YearWeek.from ( ld );
LocalDate startOfWeek = yw.atDay ( DayOfWeek.MONDAY );
Run Code Online (Sandbox Code Playgroud)
ld.toString():2019-01-01
yw.toString():2019-W01
startOfWeek.toString():2018-12-31
请注意,以周为基础的2019年中的一年的第一天如何是上一个日历年2018年而不是2019年的日期。
该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类?
| 归档时间: |
|
| 查看次数: |
8366 次 |
| 最近记录: |