我有很多时间戳,格式为“ 1231469665”,它是数据集的一部分,我正在做的任务需要我查找数据集中每个月发生了多少个事件实例。
{
int timestamp = 1231469665;
java.util.Date time = new java.util.Date((long)timestamp*1000);
}
以上给出的是“ Fri Jan 09 02:54:25 UTC 2009”,我只需要知道它的月份和年份。
你能帮我吗?
答案 0 :(得分:4)
Java time api使此操作变得容易。使用Instant.ofEpochSecond(long)
获取Instant
,然后使用LocalDateTime.ofInstant()
获取LocalDateTime
。最后,这将给您像这样的年份和月份
Instant instant = Instant.ofEpochSecond(timestamp);
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneId.of("UTC"));
System.out.printf("year = %d, month = %s%n", ldt.getYear(), ldt.getMonth());
我得到了(用于1231469665)
year = 2009, month = JANUARY
答案 1 :(得分:2)
假设您的输入1231469665
是一个整数,表示自epoch reference的1970年第一时刻的Unix时间UTC起的秒数,然后将其解析为{{1} }。
Instant
生成以标准Instant
格式表示该ISO 8601的值的文本。末尾的long secondsSinceEpoch = 1_231_469_665L;
Instant instant = Instant.ofEpochSecond( secondsSinceEpoch );
表示UTC,发音为“ Zulu”。
2009-01-09T02:54:25Z
接下来,我们需要确定该时刻的月份。诀窍在于,确定日期,进而确定月份,取决于时区。在任何给定时刻,日期都会在全球范围内变化。例如,Paris France午夜之后的几分钟是新的一天,而Montréal Québec仍然是“昨天”。按照同样的逻辑,如果在一个月的最后一天,在巴黎可能是“下个月”,而在蒙特利尔仍然是“最后一个月”。
如果未指定时区,则JVM隐式应用其当前的默认时区。该默认值可能在运行时(!)期间change at any moment,因此您的结果可能会有所不同。最好将desired/expected time zone明确指定为参数。
以Z
的格式指定proper time zone name,例如continent/region
,America/Montreal
或Africa/Casablanca
。切勿使用2-4个字母的缩写,例如Pacific/Auckland
或EST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
IST
如果要使用JVM的当前默认时区,请提出要求并作为参数传递。如果省略,则会隐式应用JVM的当前默认值。最好明确一点,因为默认值可能会在运行时的任何时候被JVM中任何应用程序的任何线程中的任何代码更改。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
定义您的时区,并将其应用于ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
,以查看该特定地区的人们使用的挂钟时间的同一时刻。
Instant
zdt.toString():2009-01-09T15:54:25 + 13:00 [太平洋/奥克兰]
现在获得一个YearMonth
对象作为一个月的整体。
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
通常最好在日期时间处理中使用“半开”方法定义时间范围。在Half-Open中,开头为包含,而结尾为专有。因此,一个月从该月初的第一时刻开始,一直到但不包括以下月的第一个月的第一时刻。
因此,我们需要获得本月的第一天。从那里得到一天的第一刻。让 java.time 确定该时刻,因为一天 not 总是在00:00:00开始。
YearMonth yearMonth = YearMonth.from( zdt ) ;
添加一个月,然后执行相同操作。
LocalDate firstOfMonth = yearMonth.atDay( 1 ) ;
ZonedDateTime zdtStart = firstOfMonth.atStartOfDay( z ) ;
我不知道您所说的“数据集”是什么意思。如果您要使用关系数据库,请使用JDBC 4.2或更高版本直接与数据库交换 java.time 对象。
JDBC规范要求支持LocalDate firstOfFollowingMonth = yearMonth.plusMonths( 1 ) ;
ZonedDateTime zdtStop = firstOfFollowingMonth.atStartOfDay( z ) ;
,但不支持OffsetDateTime
。您可以使用特定的驱动程序尝试ZonedDateTime
。如果不支持,请转换为ZonedDateTime
。
OffsetDateTime
使用OffsetDateTime start = zdtStart.toOffsetDateTime() ;
OffsetDateTime stop = zdtStop.toOffsetDateTime() ;
逻辑编写SQL。 不不要使用>= AND <
命令。
BETWEEN
在准备好的语句中使用SELECT * FROM table WHERE when >= ? AND when < ? ;
。
setObject
要检索:
myPreparedStatement.setObject( 1 , start ) ;
myPreparedStatement.setObject( 2 , stop ) ;
如果您的神秘数据集以整秒为单位运行,则可以要求OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
对象的开始和结束进行这样的计数。
ZonedDateTime
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
目前位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要long start = zdtStart.toEpochSecond() ;
long stop = zdtStop.toEpochSecond() ;
类。
在哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more。
答案 2 :(得分:0)
您不清楚是否需要格式化日期显示方式,还是要提取月份和年份。
格式:使用SimpleDateFormat(Java的任何版本)
获取月份和/或年份:java.time:,java.time.YearMonth等(仅Java8或更高版本)