当前位置: 首页 > 知识库问答 >
问题:

将日历日期格式化为dd-MM-yyyy受时区影响

周龙光
2023-03-14

我在将日历对象转换为可读字符串时遇到了一个大问题。

实际上,我使用df.format(cal.getTime())来获取格式化的字符串,这不是很好,因为我从cal.getTime()获取的Date对象不受时区的影响。

请回绝任何评论,如“使用joda时间”。。。

我正在寻找一种将日历对象直接转换为字符串的解决方案。

这些是我的格式化程序:

  private DateFormat df = new SimpleDateFormat("HH:mm", Locale.GERMANY); // 13:42 Uhr
  private DateFormat df2 = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.GERMANY); // 14.04.2012

如果你们尝试一下这段代码,你会发现Date对象不受时区的影响。

    //  this date is at wintertime
long milli = 1445945400000l;    //  CET  - central european time  

Calendar cal = Calendar.getInstance();

cal.setTimeInMillis(milli);
System.out.println("  ");
System.out.println("Kalender setTimeInMillis(" + milli + ");");
System.out.println("Daylight Time ? = " + cal.getTimeZone().useDaylightTime());
System.out.println("Date Time = " + cal.getTime());
System.out.println("Kalender Tag = " + cal.get(Calendar.DATE) + "  Monat = " + (cal.get(Calendar.MONTH) + 1) + "  Jahr = " + cal.get(Calendar.YEAR));
System.out.println("Kalender Uhrzeit = " + cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE) + ":" + cal.get(Calendar.SECOND));

cal.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
System.out.println("  ");
System.out.println("Kalender setTimeZone(TimeZone.getTimeZone(\"Europe/Berlin\");");
System.out.println("Daylight Time ? = " + cal.getTimeZone().useDaylightTime());
System.out.println("Date Time = " + cal.getTime());
System.out.println("Kalender Tag = " + cal.get(Calendar.DATE) + "  Monat = " + (cal.get(Calendar.MONTH) + 1) + "  Jahr = " + cal.get(Calendar.YEAR));
System.out.println("Kalender Uhrzeit = " + cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE) + ":" + cal.get(Calendar.SECOND));

    //  this date is at summertime
long milliS = 1445609700000l;   //  CEST - central european summertime

Calendar calS = Calendar.getInstance();

calS.setTimeInMillis(milliS);
System.out.println("  ");
System.out.println("Kalender setTimeInMillis(" + milliS + ");");
System.out.println("Daylight Time ? = " + calS.getTimeZone().useDaylightTime());
System.out.println("Date Time = " + calS.getTime());
System.out.println("Kalender Tag = " + calS.get(Calendar.DATE) + "  Monat = " + (calS.get(Calendar.MONTH) + 1) + "  Jahr = " + calS.get(Calendar.YEAR));
System.out.println("Kalender Uhrzeit = " + calS.get(Calendar.HOUR_OF_DAY) + ":" + calS.get(Calendar.MINUTE) + ":" + calS.get(Calendar.SECOND));

calS.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
System.out.println("  ");
System.out.println("Kalender setTimeZone(TimeZone.getTimeZone(\"Europe/Berlin\");");
System.out.println("Daylight Time ? = " + calS.getTimeZone().useDaylightTime());
System.out.println("Date Time = " + calS.getTime());
System.out.println("Kalender Tag = " + calS.get(Calendar.DATE) + "  Monat = " + (calS.get(Calendar.MONTH) + 1) + "  Jahr = " + calS.get(Calendar.YEAR));
System.out.println("Kalender Uhrzeit = " + calS.get(Calendar.HOUR_OF_DAY) + ":" + calS.get(Calendar.MINUTE) + ":" + calS.get(Calendar.SECOND));
Kalender setTimeInMillis(1445945400000);  
Daylight Time ? = false  
Date Time** = Tue Oct 27 11:30:00 GMT 2015  
Kalender Tag = 27  Monat = 10  Jahr = 2015  
Kalender Uhrzeit = 11:30:0  

Kalender setTimeZone(TimeZone.getTimeZone("Europe/Berlin");  
Daylight Time ? = true  
Date Time = Tue Oct 27 11:30:00 GMT 2015  
Kalender Tag = 27  Monat = 10  Jahr = 2015  
Kalender Uhrzeit = 12:30:0  

Kalender setTimeInMillis(1445609700000);  
Daylight Time ? = false  
Date Time = Fri Oct 23 14:15:00 GMT 2015  
Kalender Tag = 23  Monat = 10  Jahr = 2015  
Kalender Uhrzeit = 14:15:0  

Kalender setTimeZone(TimeZone.getTimeZone("Europe/Berlin");  
Daylight Time ? = true  
Date Time = Fri Oct 23 14:15:00 GMT 2015  
Kalender Tag = 23  Monat = 10  Jahr = 2015  
Kalender Uhrzeit = 16:15:0

共有3个答案

子车芷阳
2023-03-14

令人困惑的是,java。util。Date使用JVM的当前默认时区分配一个内部时区。无法获取或设置该区域。java。util。Java中添加了Calendar类来处理时区和其他此类问题。

长密=1445945400000l;//CET-中欧时间

通常,这样的数字是以UTC(GMT)为单位的历元计数,而不是任何特定的时区。根据该数字创建日期时间对象后,您可以指定要应用的时区。

提示:在整数文字上使用大写字母L,以避免在许多字体中看起来像1。

这些类现在已经被java淘汰了。Java 8及更高版本中内置的时间框架。新类更合理,更易于使用。

时区不仅仅是UTC的偏移量。时区是一个偏移量加上一组过去、现在和将来的规则,用于处理夏时制等异常情况。使用适当的时区,如欧洲/柏林。避免使用甚至思考3-4个字母的代码,如CET

首先,我们从epoch的计数中得到一个瞬间,即UTC时间线上的一个时刻。

long milliSecondsFromEpochInUtc = 1445945400000L;
Instant instant = Instant.ofEpochMilli ( milliSecondsFromEpochInUtc );

然后我们分配所需的时区以获取ZonedDateTime

ZoneId zoneId = ZoneId.of ( "Europe/Berlin" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );

对于输出,格式化程序默认使用ZonedDateTime对象分配的时区。

DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.MEDIUM ).withLocale ( Locale.GERMANY );
String output1 = zdt.format ( formatter );

如果指定,格式化程序可以选择应用不同的时区。

String output2 = zdt.format ( formatter.withZone ( ZoneId.of ( "America/Montreal" ) ) );

转储到控制台。

System.out.println ( "instant (UTC): " + instant );
System.out.println ( "zdt: " + zdt );
System.out.println ( "Berlin time zone: " + output1 );
System.out.println ( "Montréal time zone: " + output2 );

运行时。请注意,所有这些都代表时间线上的同一时刻。它们的呈现方式各不相同,但它们都意味着相同的同时时刻。

instant (UTC): 2015-10-27T11:30:00Z
zdt: 2015-10-27T12:30+01:00[Europe/Berlin]
Berlin time zone: 27.10.2015 12:30:00
Montréal time zone: 27.10.2015 07:30:00
苏宏峻
2023-03-14

请注意java。util。日期对象本身不包含任何时区信息-不能在日期对象上设置时区。Date对象包含的唯一内容是自“epoch”起的毫秒数-1970年1月1日,UTC 00:00:00。

看见https://stackoverflow.com/a/2892156/5445351

糜正业
2023-03-14

您需要设置格式化程序的时区,一个简单的示例:

SimpleDateFormat df = new SimpleDateFormat();

Calendar cal1 = Calendar.getInstance(TimeZone.getTimeZone("GMT+4:00"));

df.setTimeZone(cal1.getTimeZone());
System.out.println(df.format(cal1.getTime()));

Calendar cal2 = Calendar.getInstance(TimeZone.getTimeZone("GMT-3:00"));

df.setTimeZone(cal2.getTimeZone());
System.out.println(df.format(cal2.getTime()));

输出:

10/30/15 1:02 PM
10/30/15 6:02 AM
 类似资料:
  • 这将产生。但我需要的是。我的目的是使用Hibernate标准将此日期与数据库中的另一个日期进行比较。所以我需要格式的date对象。

  • 问题内容: 如何将日历日期转换为格式。 这将产生。但是我需要的是。我的目的是使用条件将此日期与数据库中的另一个日期进行比较。所以我需要格式的日期对象。 问题答案: Java是自1970年1月1日格林尼治标准时间00:00:00以来的毫秒数的容器。 当你使用时,Java将使用打印内容。 更改它的唯一方法是重写Date并提供你自己的实现。现在,在启动IDE并尝试执行此操作之前,我不会这样做。它只会使事

  • 问题内容: 好吧,我正在使用a进行详细说明,因为我从数据库中获取了一个对象,并且从同一对象中获得了一个变量“ fecha”(日期),因此我得到了a ,因此formatt以毫秒为单位,但是我不想出现毫秒。因此,我需要将我从数据库中收到的日期格式化为没有毫秒的新日期。 这是对象Factura: 在映射到数据库的xml中,我具有该变量“ fecha”的代码: 在数据库中,该列为。 当我从数据库中获取一个

  • 问题内容: 我正在尝试从转换日期。我已经使用了mktime()函数和其他函数,但是我似乎无法使其工作。我已经成功地将原始日期用作定界符,但更改格式并将其与交换时没有成功。 任何帮助将不胜感激。 问题答案: 通过查看各个组成部分之间的分隔符,可以消除或格式中的日期的歧义:如果该分隔符是斜杠(),则假定为American ;否则,为0。反之,如果分隔符是破折号()或点(),则采用欧洲格式。 使用默认的

  • 我有一个格式为。我希望它的格式为 下面是我尝试进行此转换的示例util: 但是,我得到的输出不是格式。 请告诉我如何将从格式化为

  • 我的输入值是'13/5/201412:00:00am',我需要将此格式更改为'2014-5-1300:00:00',但所有的datetime变量都是以dd-mm-yyyy格式返回的。我不想将日期转换为字符串,我希望将日期值存储在datetime属性中,并使用'yyyy-mm-dd'格式: