我使用以下功能在我应用TimeZone“Europe / Warsaw”后的几秒钟内获得时间。
我正确地获取日期,但是只要我在几秒钟内转换日期,我的输出就会出错。服务器在TimeZone“Europe / Warsaw”中预计秒数。什么是摆脱这种情况的最佳方式?
public static long getTimeInSeconds() {
try {
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//Here you say to java the initial timezone. This is the secret
sdf.setTimeZone(TimeZone.getTimeZone("Europe/Warsaw"));
//Will get in Warsaw time zone
String date = sdf.format(calendar.getTime());
Date date1 = sdf.parse(date);
//Convert time in seconds as required by server.
return (date1.getTime() / 1000);
} catch (ParseException e) {
e.printStackTrace();
}
return 0;
}
答案 0 :(得分:4)
“TimeZone中的秒”没有意义,因为纪元秒表示“纪元以来的秒数”(其中< strong> epoch 1970年1月1日UTC的午夜),无论时区如何。
这个价值在世界各地都是一样的。但是,相同的纪元秒值可以转换为本地日期和时间,具体取决于时区。
示例:现在,epoch第二个值是1520352472.这个相同的值(自纪元以来的1520352472秒),在世界各地都是一样的。但是这个值可以代表每个时区的不同日期和时间:
事情是:无论我在哪个时区,epoch秒值都是相同的,所以你根本不需要考虑任何时区。
java.util.Date
类doesn't have any notion of timezone,它只包含一个long
值,表示自纪元以来的毫秒数。所以,如果你有一个Date
对象,只需使用这个值并除以1000:
long epochSeconds = new Date().getTime() / 1000;
实际上,如果您想要只当前日期/时间的数值,您甚至无需创建Date
来获取它:
long epochSeconds = System.currentTimeMillis() / 1000;
答案 1 :(得分:1)
要获取自1970-01-01T00:00Z的纪元参考以来的整秒计数:
Instant.now().getEpochSecond()
替代路线,结果相同:
ZonedDateTime.now( ZoneId.of( "Europe/Warsaw" ) ).toInstant().getEpochSecond()
摆脱这种情况的最佳方法是什么?
最好的方法是使用几年前取代了可怕的Date
,Calendar
和SimpleDateFormat
类的现代 java.time 类。
显然您想要两件事:
第一个,获取当前时区的时刻。我们使用ZoneId
和ZonedDateTime
类。
ZoneId z = ZoneId.of( "Europe/Warsaw" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
请参阅此code run live at IdeOne.com。
zdt.toString():2020-02-09T21:14:56.417009 + 01:00 [欧洲/华沙]
要获取自1970-01-01T00:00Z以来的秒数,请提取Instant
。此类表示以UTC表示的时刻,其偏移量为零小时-分钟-秒。
Instant instant = zdt.toInstant() ;
请参阅此code run live at IdeOne.com。
instant.toString():2020-02-09T20:14:56.417009Z
变量zdt
和instant
代表时间轴上的同一时刻,同一点。只有挂钟时间不同。
询问从纪元参考开始的整秒计数。
long secondsSinceEpoch = instant.getEpochSecond() ; // Beware of data-loss, as fractional second is ignored.
请参阅此code run live at IdeOne.com。
secondsSinceEpoch:1581279296
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
要了解更多信息,请参阅Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规范为JSR 310。
Joda-Time项目(现在位于maintenance mode中)建议迁移到java.time类。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容打下了基础。您可能会在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more。
答案 2 :(得分:0)
您需要在从日历中获取时间后设置时区
public static long getTimeInSeconds() {
try {
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//Will get in Warsaw time zone
String date = sdf.format(calendar.getTime());
//Here you say to java the initial timezone. This is the secret
sdf.setTimeZone(TimeZone.getTimeZone("Europe/Warsaw"));
Date date1 = sdf.parse(date);
//Convert time in seconds as required by server.
return (date1.getTime() / 1000);
} catch (ParseException e) {
e.printStackTrace();
}
return 0;
}