将英国时间转换为南非时间的Java

时间:2015-11-24 09:24:16

标签: java date datetime

我的足球比赛日期和时间是英国时间。 我在南非运行这项服务所以必须在南非时间显示固定日期和时间。目前我正在这样做:

int kickoffHour = fixture.getTime().getHours() + 2;

然而 - 当它到达2016年3月底时,这将不得不再次改为“+ 1”而不是“+ 2”。现在我无法改变这一点,所以我想要一些会自动获取其DST或BST并进行转换的内容。

我尝试过这样的事情:

SimpleDateFormat sdf =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("Europe/London"));
Date date = sdf.parse(fixture.getDate() + " " + fixture.getTime());

但这让我像凌晨2点或其他什么。我在数据库中的日期是:2015-12-16,数据库中的时间是16:00:00 - 解析后我得到12月16日星期二02:00:00 2015年

4 个答案:

答案 0 :(得分:1)

显然,您指的是夏令时(DST)所需的调整。您应该将这些工作留给一个好的日期时间库,而不是自己管理这些细节。

不幸的是,与早期版本的Java捆绑在一起的旧日期时间类并不好。虽然是勇敢的努力,但它们在设计和实施方面都被证明是麻烦和混乱的。避免使用java.util.Date/.Calendar和java.text.SimpleDateFormat。

java.time

Java 8及更高版本中内置的java.time框架取代了棘手的旧java.util.Date/.Calendar类。新课程的灵感来自非常成功的Joda-Time框架,旨在作为其继承者,在概念上类似但重新设计。由JSR 310定义。由ThreeTen-Extra项目扩展。请参阅Tutorial

顺便说一句,最佳做法是完成所有业务逻辑,数据存储和操作。交换,数据库工作在UTC。仅在用户或数据接收器预期时使用分区日期时间值。但是,看起来你在伦敦时间被给了一个字符串,所以让我们一起去。

String input = "2015-12-16 16:00:00"; // Local date-time in United Kingdom (London).

使用proper time zone names。切勿使用常见的3-4字母代码,因为它们既不标准也不唯一。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "yyyy-MM-dd HH:mm:ss" );

您的字符串输入缺少有关其offset-from-UTC或时区的嵌入信息。因此,我们将假设 String表示Europe/London中的本地时间。我们将此假设传达给DateTimeFormatter,否则它会将传入的String解释为属于JVM的当前默认时区。请注意,java.time使用immutable objects,因此我们不是更改格式化程序,而是根据旧实例的值生成新实例。

ZoneId zoneId_London = ZoneId.of ( "Europe/London" );
formatter = formatter.withZone ( zoneId_London ); // Specify the zone by which to interpret this date-time input string as it lacks any offset or time zone info.
ZonedDateTime zdt_UK = ZonedDateTime.parse ( input , formatter );

随着伦敦的约会时间到来,我们可以调整到南非的时区。

ZoneId zoneId_Johannesburg = ZoneId.of ( "Africa/Johannesburg" );
ZonedDateTime zdt_ZA = zdt_UK.withZoneSameInstant ( zoneId_Johannesburg );

转储到控制台。

System.out.println ( "input: " + input + " in zone: " + zoneId_London + " = " + zdt_UK );
System.out.println ( "zdt_UK: " + zdt_UK + " adjusted to zone: " + zoneId_Johannesburg + " is: " + zdt_ZA );
  

输入:2015-12-16 16:00:00区域:欧洲/伦敦= 2015-12-16T16:00Z [欧洲/伦敦]

     

zdt_UK:2015-12-16T16:00Z [欧洲/伦敦]调整为区域:非洲/约翰内斯堡是:2015-12-16T18:00 + 02:00 [非洲/约翰内斯堡]

最后,我们在UTC工作的大部分工作。为此,提取一个Instant对象,该对象是UTC时间轴上的一个时刻。

Instant instant = zdt_ZA.toInstant();

答案 1 :(得分:0)

如果fixture.getDate() + " " + fixture.getTime()工作正常,最后您将获得String "2015-12-16 16:00:00"

然后我简单地格式化返回日期。我的工作正常..

public static void main(String[] args) throws ParseException {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("Europe/London"));
    Date date = sdf.parse("2015-12-16 16:00:00");
    //Date date = sdf.parse("2016-03-31 23:50:50");

    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    df.setTimeZone(TimeZone.getTimeZone("Africa/Johannesburg"));
    System.out.println(df.format(date));
}

此代码的输出为2015-12-16 18:00:00

当我使用评论date个对象时,结果为2016-04-01 00:50:50

答案 2 :(得分:0)

您只需从灯具中获取时间值,然后使用日历自动转换您的时区。我记住你的系统时区与预期的输出时区匹配。请检查下面的代码snipet,没有使用fixture对象并使用硬编码值。

    Calendar cal = Calendar.getInstance();
    cal.setTimeZone(java.util.TimeZone.getTimeZone("Europe/London"));

    cal.set(Calendar.HOUR, 16);
    cal.set(Calendar.MINUTE, 0);
    cal.set(2015, 11, 24);

    System.out.println(cal.getTimeZone());
    System.out.println(cal.getTime()); //printing in IST (my local time)

答案 3 :(得分:-1)

您应该拥有数据库中的Date对象。 如果你想打印它,使用你的SimpleDateFormat设置它的时区到南非"非洲/约翰内斯堡"它会起作用。

Date myDate;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("Africa/Johannesburg"));
System.out.println(sdf.format(myDate));