java.util.Date-测试转换US<-&燃气轮机;英国
下面是我的测试代码 行///1///和///2///是可选的 如果我使用第///2///行,输出看起来有问题,似乎它不能解释美国波士顿和英国伦敦全年相差5小时的事实。如果我使用第///1///行,它看起来不错,似乎可以解释这个事实。为什么会这样?概念上的区别在哪里?为什么像这样将两个日期移动1天(我的意思是///2//)是不正确的java.util.Date-测试转换US<-&燃气轮机;英国,java,date,datetime,timezone,date-conversion,Java,Date,Datetime,Timezone,Date Conversion,下面是我的测试代码 行///1///和///2///是可选的 如果我使用第///2///行,输出看起来有问题,似乎它不能解释美国波士顿和英国伦敦全年相差5小时的事实。如果我使用第///1///行,它看起来不错,似乎可以解释这个事实。为什么会这样?概念上的区别在哪里?为什么像这样将两个日期移动1天(我的意思是///2//)是不正确的 import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Tim
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class TimeZoneExample02 {
// private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
public static void main(String[] args) {
Calendar bostonTime = Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
Calendar londonTime = new GregorianCalendar(TimeZone.getTimeZone("Europe/London"));
londonTime.setTimeInMillis(bostonTime.getTimeInMillis());
bostonTime.getTime();
londonTime.getTime();
for (int i=0; i>=-500; i--){
bostonTime.add(Calendar.DATE, -1);
// londonTime.setTimeInMillis(bostonTime.getTimeInMillis()); /// 1 ///
londonTime.add(Calendar.DATE, -1); /// 2 ///
bostonTime.getTime();
londonTime.getTime();
System.out.printf("Boston time: %s", getString(bostonTime));
System.out.print(" /// ");
System.out.printf("London time: %s\n", getString(londonTime));
}
}
private static String getString(Calendar c){
StringBuilder sb = new StringBuilder();
sb.append(c.get(Calendar.YEAR));
sb.append("-");
sb.append(String.format("%02d", c.get(Calendar.MONTH) + 1));
sb.append("-");
sb.append(String.format("%02d", c.get(Calendar.DAY_OF_MONTH)));
sb.append(" ");
sb.append(String.format("%02d", c.get(Calendar.HOUR_OF_DAY)));
sb.append(":");
sb.append(String.format("%02d", c.get(Calendar.MINUTE)));
sb.append(":");
sb.append(String.format("%02d", c.get(Calendar.SECOND)));
sb.append(".");
return sb.toString();
}
}
产出1:
波士顿时间:2013-10-30 18:51:12伦敦时间:2013-10-30 22:51:12。波士顿时间:2013-10-2918:51:12伦敦时间:2013-10-29 22:51:12。
波士顿时间:2013-10-2818:51:12伦敦时间:2013-10-28 22:51:12。
波士顿时间:2013-10-27 18:51:12伦敦时间:2013-10-27 22:51:12。
波士顿时间:2013-10-26 18:51:12伦敦时间:2013-10-26 23:51:12。
波士顿时间:2013-10-2518:51:12伦敦时间:2013-10-25 23:51:12。
波士顿时间:2013-10-2418:51:12伦敦时间:2013-10-24 23:51:12 产出2: 波士顿时间:2013-10-30 18:50:53伦敦时间:2013-10-30 23:50:53。
波士顿时间:2013-10-2918:50:53伦敦时间:2013-10-29 23:50:53。
波士顿时间:2013-10-2818:50:53伦敦时间:2013-10-28 23:50:53。
波士顿时间:2013-10-27 18:50:53伦敦时间:2013-10-27 23:50:53。
波士顿时间:2013-10-26 18:50:53伦敦时间:2013-10-26 23:50:53。
波士顿时间:2013-10-2518:50:53伦敦时间:2013-10-25 23:50:53。
波士顿时间:2013-10-2418:50:53伦敦时间:2013-10-2423:50:53 伦敦夏令时 2013年10月27日,伦敦时间发生了变化,凌晨2点变为凌晨1点(再次) 功能,而不是bug 在顶部的讨论中解释说,
与set()不同,add()强制立即重新计算日历的毫秒数和所有字段。
此外,add
方法上的注释指出,较小的时间单位不会调整。该文件特别指出,HOUR
是一个较小的字段,它比DAY\u\u\u\u\u月
的字段小,因此不进行调整。也就是说,开始时是23小时,结束时是23小时,之后是毫秒,需要时重新计算
您看到的set
和add
方法的行为都是正确的功能,而不是bug。
间接回答
捆绑的java.util.Calendar和java.text.SimpleDataFormat是出了名的麻烦、混乱和棘手。它们在设计和实现上都有缺陷
我理解您对“使用Java的内置功能”的兴趣。虽然这种兴趣通常是值得称赞的,但在Java的这个特定角落,这是浪费时间。甚至Sun和Oracle也放弃了这些课程。带来了一个全新的java.time.*包,它由旧的捆绑类定义、启发并取代了旧的捆绑类
如果您还不能迁移到Java8,请使用。Joda Time在Java的多个版本中工作,并在Java 8中继续工作,因为它是积极维护的
示例代码
一些使用2.3的示例代码帮助您继续
一些注释…
乔达时间实际上知道自己的时区。相反,java.util.Date没有时区,但是它的toString
方法应用了JVM的默认时区,这造成了无尽的混乱
请注意,在本例中,dateTime\u Boston
和dateTime\u London
自epoch起具有相同的毫秒数
默认情况下,Joda Time为字符串输出使用标准格式,如下所示2014-02-13T10:32:28.131+05:30
末尾的+
或-
标记UTC/GMT的时区偏移量。请勿将其作为公式中的操作数读取。将其理解为一个标签,例如,“印度的时区偏移为+05:30,因此显示的日期时间比UTC/GMT早五个半小时”
- 加号(“+”)表示UTC/GMT之前
- 连字符减号(“-”)表示UTC/GMT之后
Z
发音为“Zulu”,是+00:00
的缩写。这意味着UTC/GMT时区,即没有时区偏移
//指定时区,而不是依赖默认值。
DateTimeZone timeZone_Boston=DateTimeZone.forID(“美国/纽约”);
DateTimeZone timeZone_London=DateTimeZone.forID(“欧洲/伦敦”);
DateTime DateTime_Boston=新的日期时间(2013、10、27、22、51、12,时区_Boston);
DateTime DateTime_London=DateTime_Boston.toDateTime(时区_London);
DateTime Early_London=DateTime_London.minus天数(2);//使用“2”在DST更改前通知我们。
DateTime earlier\u UtcGmt=earlier\u London.toDateTime(DateTimeZone.UTC);
转储到控制台
System.out.println(“dateTime\u Boston”+dateTime\u Boston);
System.out.println(“dateTime_London”+dateTime_London);
System.out.println(“早伦敦”+早伦敦);
System.out.println(“更早的UtcGmt”+更早的UtcGmt);
当运行时
波士顿时间2013-10-27T22:51:12.000-04:00
伦敦时间2013-10-28T02:51:12.000Z
伦敦时间2013-10-26T02:51:12.000+01:00
早于2013-10-26T01:51:12.000Z
Tangent:使用JodaTime库而不是java.util.Date。您认为哪里不对?您不期望的输出是什么?我看不出这段代码有什么问题(当然,除了偶尔的多余部分)。是的,我在这里已经听过好几次了。但是第一次想利用Java的内置功能。///2///是错误的,因为它表明波士顿和伦敦总是有5个小时的时间差,而这不是全年的情况(我相信是这样)。例如,在2013年10月30日,差异仅为4小时(因为伦敦和波士顿在不同的日子改变冬夏季节)1///在这方面还可以。哎呀,我想我意识到了概念上的差异。换班1天并不意味着我在换班