我得到一个格式为yyyy-MM-dd HH: mm的字符串,它代表UTC中的日期和时间。下一步是将其放入日历(带时间区UTC)。
此外,还需要创建一个单独的日历,将UTC转换为“欧洲/伦敦”时区(GMT/BST)。
之后,我需要能够检测“欧洲/伦敦”日历是否有DST(日光节约补偿)。
下面的代码将告诉你我已经走了多远,它在一台默认系统时区为GMT的英国计算机上运行正常。但是,当我在一台时区为UTC的pc上运行它时,它会失败。它似乎无法告诉我是否存在DST_偏移(它始终为零)。
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.set(Calendar.YEAR, 2016);
cal.set(Calendar.MONTH, 1);
cal.set(Calendar.DAY_OF_MONTH, 27);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 35);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
//This is required as Java Date JAN starts at 0.
int MonthCon = cal.get(Calendar.MONTH)-1;
cal.set(Calendar.MONTH, MonthCon);
Date d = cal.getTime();
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssz");
f.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("UTC: " + f.format(d));
f.setTimeZone(TimeZone.getTimeZone("Europe/London"));
System.out.println("BST: " + f.format(d));
//Creates a BST calendar of the same UTC time
String dateStrBST = f.format(d);
SimpleDateFormat curFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssz");
curFormater.setTimeZone(TimeZone.getTimeZone("Europe/London"));
Date dateObjBST = curFormater.parse(dateStrBST);
System.out.println("BSTNewDate: " + f.format(dateObjBST));
Calendar calBST = Calendar.getInstance(TimeZone.getTimeZone("BST"));
calBST.setTime(dateObjBST);
System.out.println("Current TimeZone is : " + calBST.getTimeZone());
int offset = calBST.get(Calendar.DST_OFFSET);
System.out.println("Day Light Savings: "+offset);
System.out.println("Transition Day: "+isDSTTransitionDay(cal.get(Calendar.YEAR),cal.get(Calendar.MONTH),cal.get(Calendar.DAY_OF_MONTH))+" Transition Type: "+DSTtransitionType(cal.get(Calendar.YEAR),cal.get(Calendar.MONTH),cal.get(Calendar.DAY_OF_MONTH)));
不幸的是,我需要能够检测任何特定的一天是否是过渡日,也就是说,从DST开/关或关/开变化的一天。这同样适用于本地计算机,但不适用于UTC时区1。
private static boolean isDSTTransitionDay(int year, int month, int day) throws ParseException
{
Calendar calStartofDay = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calStartofDay.set(Calendar.YEAR, year);
calStartofDay.set(Calendar.MONTH, month);
calStartofDay.set(Calendar.DAY_OF_MONTH, day);
calStartofDay.set(Calendar.HOUR_OF_DAY, 00);
calStartofDay.set(Calendar.MINUTE, 0);
calStartofDay.set(Calendar.SECOND, 1);
Date dStartofDay = calStartofDay.getTime();
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssz");
f.setTimeZone(TimeZone.getTimeZone("Europe/London"));
String dateStrUTCtoBST = f.format(dStartofDay);
SimpleDateFormat curFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssz");
curFormater.setTimeZone(TimeZone.getTimeZone("Europe/London"));
Date dateObjBST = curFormater.parse(dateStrUTCtoBST);
Calendar calBST = Calendar.getInstance();
calBST.setTime(dateObjBST);
int offsetStart = calBST.get(Calendar.DST_OFFSET);
calBST.add(Calendar.HOUR_OF_DAY, 23);
int offsetEnd = calBST.get(Calendar.DST_OFFSET);
//System.out.println("Start: "+offsetStart+" End: "+offsetEnd);
if (offsetEnd == offsetStart)
{
return false;
}else
{
//if(offsetStart<offsetEnd) {System.out.println("Transition to BST");}else{System.out.println("Transition to UTC/GMT");};
return true;
}
}
因此,在UTC计算机上,由于它总是放置日历,因此出现了严重的故障。DST_偏移量为零。我显然误解了一些事情,所以任何帮助/澄清都是好的。
在代码的其他部分使用日历时,我几乎必须保留日历,但我意识到Java8有很多更奇特的方式来做事情。
你正在使用
Calendar calBST = Calendar.getInstance();
这将calBST设置为计算机的时区(在UTC计算机上,它将是UTC)。
calBST。设置时间(dateObjBST)
设置时间,而不是时区。
试着在那里使用
getInstance(时区)
。
在任何情况下,我会这样替换你的代码:
Calendar calStartofDay = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calStartofDay.set(Calendar.YEAR, 2017);
calStartofDay.set(Calendar.MONTH, 0);
calStartofDay.set(Calendar.DAY_OF_MONTH, 21);
calStartofDay.set(Calendar.HOUR_OF_DAY, 00);
calStartofDay.set(Calendar.MINUTE, 0);
calStartofDay.set(Calendar.SECOND, 1);
Calendar calBST = Calendar.getInstance(TimeZone.getTimeZone("Europe/London"));
calBST.setTimeInMillis(calStartofDay.getTimeInMillis());
// use this to check the time
System.out.printf("%tc%n", calBST);
此外,从日历文档中,请注意以下事项:
set(f,value)将日历字段f更改为value。此外,它还设置了一个内部成员变量,以指示日历字段f已被更改。尽管日历字段f会立即更改,但在下一次调用get()、getTime()、getTimeInMillis()、add()或roll()之前,不会重新计算日历的时间值(以毫秒为单位)。因此,多次调用set()不会触发多次不必要的计算。使用set()更改日历字段后,其他日历字段也可能会更改,具体取决于日历字段、日历字段值和日历系统。此外,在重新计算日历字段后,get(f)不一定返回通过调用set方法设置的值。具体细节由具体的日历类决定。
请允许我说实话,我试图阅读你的代码,但并不真正理解你试图获得你想要的东西的方式。如果可以使用Java8,我建议切换到使用Java8日期和时间类。有了这些,你的工作并不复杂。在我选择的去年10月30日的示威活动中,英国(和欧盟)将夏时制改为标准时间。
String originalDate = "2016-10-30 23:35";
LocalDateTime localTime = LocalDateTime.parse(originalDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
ZonedDateTime utcTime = localTime.atZone(ZoneOffset.UTC);
ZonedDateTime bstTime = utcTime.withZoneSameInstant(ZoneId.of("Europe/London"));
// the summer time offset is how many milliseconds?
long dstOffset = ChronoUnit.MILLIS.between(utcTime.toLocalDateTime(), bstTime.toLocalDateTime());
System.out.println(dstOffset); // prints 0
// try the same at start of day (midnight)
utcTime = utcTime.toLocalDate().atStartOfDay(ZoneOffset.UTC);
bstTime = utcTime.withZoneSameInstant(ZoneId.of("Europe/London"));
dstOffset = ChronoUnit.MILLIS.between(utcTime.toLocalDateTime(), bstTime.toLocalDateTime());
System.out.println(dstOffset); // prints 3600000
// and next midnight
utcTime = utcTime.plusDays(1);
bstTime = utcTime.withZoneSameInstant(ZoneId.of("Europe/London"));
dstOffset = ChronoUnit.MILLIS.between(utcTime.toLocalDateTime(), bstTime.toLocalDateTime());
System.out.println(dstOffset); // prints 0
2018-03-26 09:04:14Z 2018-03-26 14:34:14+05:30 2018-03-26 11:04:14+02:00
从“GMT夏令时”或任何其他可用的Windows时区信息有什么方法可以到达BST吗?
如果英国是格林尼治标准时间(一年的一半),这工作良好时,投入一个活动。然而,在英国夏令时,该事件在创建时会延迟一个小时。如何输入时区或创建正确处理GMT或BST的日期。还有没有更好的方法来完成我到目前为止所做的事情呢? 多谢。
我有一个日历对象的问题,它没有显示美国/圣地亚哥时区的DST(每日节约时间)的正确偏移:我的示例代码:time zone from time zone = time zone . gettimezone("美国/圣地亚哥"); 输出为:偏移量:-4在2015年3月31日的美国/圣地亚哥时区,偏移量应为-3。(参考:http://www.timeanddate.com/worldclock/conv
问题内容: SQL Server作业/计划-美国与英国夏令时调整 我们有一台基于英国的服务器,需要在16:30(美国中部时间-这可能很奇怪,但这是由于某些数据的可用性)运行SQL Agent Job。通常这不会造成问题,因为英国和美国之间的时差为6个小时,因此我们将工作安排在22:30进行。 但是,由于英美两国在3月和11月的不同时间调整时钟以节省夏令时,因此英美之间的时差为5个小时,为2周。 我
我有一个Java客户机,它正在以UTC格式在MySQL DB中插入(通过CSV和'Load DATA Infile')时间戳(type TIMESTAMP)。我的服务器的时区是“America/New_York”,我需要保留夏令时信息。11月5日凌晨2点是美国东部时间转换到东部时间的时候,时钟拨回一个小时到凌晨1点。例如,11月5日凌晨1:30,发生两次;EDT和EST各一次。 我该如何让服务器区