Java 如何表示特定的日历周期(月、周等)
据我所知,Joda time的主要概念是:Java 如何表示特定的日历周期(月、周等),java,jodatime,Java,Jodatime,据我所知,Joda time的主要概念是: 具有毫秒粒度的即时时间(由DateTime表示) Interval表示两个实例的跨度 持续时间实际上只是一个长的毫秒数 一个周期,它类似于一个未锚定的时间长度,它不是以精确的毫秒数定义的,而是根据诸如“月”、“日”等概念的常见民间用法定义的 那么我应该如何表示,例如“2014年2月”。有那种类型的吗?我知道我可以将其表示为一个瞬间的元组(在该月的开始或结束时)和一个月的周期。但这意味着我在Joda的基础上定义了自己的类型,并且我必须决定一个约定,即
- 具有毫秒粒度的即时时间(由
表示)DateTime
表示两个实例的跨度Interval
- 持续时间实际上只是一个
毫秒数长的
- 一个
,它类似于一个未锚定的时间长度,它不是以精确的毫秒数定义的,而是根据诸如“月”、“日”等概念的常见民间用法定义的周期
周期。但这意味着我在Joda
的基础上定义了自己的类型,并且我必须决定一个约定,即该瞬间是在我希望定义的时间段的开始还是结束(因为这两个选项显然都是可行的)
我拥有的用例是,我需要生成报告,如果用户:
- 只是碰巧选择了两个恰好在2014年2月初和2月底的实例
- 被选中为2014年2月编制月度报告
那么,有没有一种单一的类型?如果失败了,那么什么是最好的方法来表示它。中的类提供了这个功能,持续了几个月
因此,要获取1970年1月和历元第一个月开始和结束实例的历元值后的秒数:
YearMonth yearMonth = new YearMonth (1970, 1);
Interval interval = yearMonth.toInterval(DateTimeZone.UTC);
int startSSE = (int) TimeUnit.MILLISECONDS.toSeconds(interval.getStartMillis());
int endSSE = (int) TimeUnit.MILLISECONDS.toSeconds(interval.getEndMillis());
System.out.printf("%d -> %d (%4.6f days)\n", startSSE, endSSE, ((float)(endSSE-startSSE))/(24*60*60));
目前我在Joda Time YearMonth类中的运气不好,所以这里有一个使用DateTimeFormatter的替代示例
public static DateTimeFormatter DATEFORMATTER = new DateTimeFormatterBuilder()
.appendPattern("MMM, YYYY").toFormatter();
我为您添加了println()的示例代码
/**
* calculates the number of months between the upper and lower bounds
* example: int m = numberOfMonths("January, 2009", "May, 2000");
* >m=104
* Uses Joda
* Months are full month names
* @return
*/
public int numberOfMonths(String upperMMMMcommaYYYY, String lowerMMMMcommaYYYY){
DateTime upper = DATEFORMATTER.parseDateTime(upperMMMMcommaYYYY);
DateTime lower = DATEFORMATTER.parseDateTime(lowerMMMMcommaYYYY);
Months m = Months.monthsBetween(lower, upper);
System.out.println(upperMMMMcommaYYYY.concat("printed from DateTime looks like ".concat(upper.toString(DATEFORMATTER))));
return m.getMonths;
}
使用DateTimeFormatter+DateTime的println结果->2009年1月看起来像2009年1月tl;博士
使用现代java.time类取代Joda time项目和最初与java最早版本捆绑在一起的麻烦的旧遗留日期时间类
YearMonth.of( 2014 , Month.FEBRUARY )
java.time
现代方法使用java.time(JSR310)类,这些类是Joda time项目的正式继承者。这两个项目都由同一个人斯蒂芬·科尔伯恩领导
YearMonth
那么我应该如何表示,例如“2014年2月”
使用专门为此设计的
您可以使用1月至12月的sane编号1-12,按编号指定年和月(与传统类不同)
或者使用方便的枚举
ISO 8601
要将年-月表示为文本,请使用标准格式:YYYY-MM
String output = ym.toString() ;
2014-02
还有这样的弦
YearMonth ym = YearMonth.parse( "2014-02" ) ;
据我所知,没有数据库具有年-月数据类型。因此,我建议在表中使用一个文本列,其中包含ISO 8601格式的字符串。请注意,此ISO 8601格式的字母排序碰巧也是按时间顺序排序的
Period
一个月的时间
期间
未附加到时间线。类似于Period.ofMonths(1)
的内容表示与任何日期或日历无关的通用月份
相反,YearMonth
表示一个特定的月份。将YearMonth
附加到时间线
片刻
如果您需要特定的日期和时间,例如查询数据库,则需要确定日期。该类表示一个仅限日期的值,不包含一天中的时间和时区
LocalDate ldStart = ym.atDay( 1 ) ; // First of the month.
LocalDate ldStop = ym.plusMonths( 1 ).atDay( 1 ) ; // First day of the following month.
使用时间值确定日期需要时区
LocalDate ldStart = ym.atDay( 1 ) ; // First of the month.
LocalDate ldStop = ym.plusMonths( 1 ).atDay( 1 ) ; // First day of the following month.
时区对于确定有时间的日期至关重要。在任何一个特定的时刻,世界各地的日期都因地区而异。例如,中午夜后几分钟是新的一天,而中仍然是“昨天”
如果未指定时区,JVM将隐式应用其当前默认时区。该默认值可能随时更改,因此您的结果可能会有所不同。最好将所需/预期时区明确指定为参数
以大陆/地区
的格式指定,例如,或太平洋/奥克兰
。切勿使用3-4个字母的缩写,如EST
或IST
,因为它们不是真正的时区,也不是标准化的,甚至不是唯一的(!)
使用该区域让java.time确定一天中的第一个时刻。不要假设一天从00:00:00开始。某些区域中的某些日期在一天中的其他时间开始,例如01:00:00
ZonedDateTime zdtStart = ldStart.atZone( z ) ; // First moment of the day starting in the wall-clock time used by the people of a particular region (a time zone).
ZonedDateTime zdtStop = ldStop.atZone( z ) ;
然后,您可以提取UTC值,数据库通常使用这些值将值存储在SQL standardTIME Stamp WITH TIME ZONE
的列中
Instant instantStart = zdtStart.toInstant() ;
Instant instantStop = zdtStop.toInstant() ;
JDBC
从JDBC4.2及更高版本开始,您可以与数据库交换java.time对象
myPreparedStatement.setObject( … , instantStart ) ;
myPreparedStatement.setObject( … , instantStop ) ;
检索
Instant instant = myResultSet.getObject( … , Instant.class ) ;
关于java.time
该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&
该项目现已启动,建议迁移到类
要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是
您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要java.sql.*
类
从哪里获得java.time类
- 然后
- 内置的李>
- 标准JavaAPI的一部分,带有捆绑实现
- Java9添加了一些次要功能和修复
- 及
- 大部分java.time功能都在中向后移植到Java6和Java7
-
- 更高版本的Android捆绑包实现了java.time类
- 对于早期的Android(我在实现报表时也有同样的要求。我最终实现了自己的类,包含startdate、enddate、periodName、periodType(周、月、季度……)
myPreparedStatement.setObject( … , instantStart ) ;
myPreparedStatement.setObject( … , instantStop ) ;
Instant instant = myResultSet.getObject( … , Instant.class ) ;