如何仅从Unix时间戳获取月份和年份

时间:2018-11-24 22:12:36

标签: java

我有很多时间戳,格式为“ 1231469665”,它是数据集的一部分,我正在做的任务需要我查找数据集中每个月发生了多少个事件实例。

{
  int timestamp = 1231469665;
  java.util.Date time = new java.util.Date((long)timestamp*1000);
}

以上给出的是“ Fri Jan 09 02:54:25 UTC 2009”,我只需要知道它的月份和年份。

你能帮我吗?

3 个答案:

答案 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/regionAmerica/MontrealAfrica/Casablanca。切勿使用2-4个字母的缩写,例如Pacific/AucklandEST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

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.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance 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中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

答案 2 :(得分:0)

您不清楚是否需要格式化日期显示方式,还是要提取月份和年份。