转换 GMT 日期时间字符串

发布于 2024-11-24 21:32:05 字数 720 浏览 5 评论 0 原文

我对 Java 还很陌生,并且对使用 SimpleDateFormatCalendar 有点困惑。我有一个日期对象,想要提取像 yyyy-MM-dd HH:mm:ss 这样的 GMT 日期字符串。我住在德国,现在是 GMT +0200。例如,我的日期对象的时间是 2011-07-18 13:00:00。我现在需要的是2011-07-18 11:00:00。我的时区的偏移量应该自动计算。

我尝试了类似的方法,但我猜想某处存在错误:

private String toGmtString(Date date){
    SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    TimeZone timeZone = TimeZone.getDefault();
    Calendar cal = Calendar.getInstance(new SimpleTimeZone(timeZone.getOffset(date.getTime()), "GMT"));
    sd.setCalendar(cal);
    return sd.format(date);
}

在某些设备上,日期字符串按照我想要的方式返回。在其他设备上,偏移量计算不正确,我从输入日期对象接收日期和时间。你能给我一些提示或建议吗?我想我的默认时区方法不起作用?

I am pretty new to Java and I am a little stuck with using SimpleDateFormat and Calendar. I have a Date-Object and want to extract a GMT datestring like yyyy-MM-dd HH:mm:ss. I live in Germany and at the moment we are GMT +0200. My Date-Object's time is for example 2011-07-18 13:00:00. What I need now is 2011-07-18 11:00:00. The offset for my timezone should be calculated automatically.

I tried something like this, but I guess there is a fault somewhere:

private String toGmtString(Date date){
    SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    TimeZone timeZone = TimeZone.getDefault();
    Calendar cal = Calendar.getInstance(new SimpleTimeZone(timeZone.getOffset(date.getTime()), "GMT"));
    sd.setCalendar(cal);
    return sd.format(date);
}

On some devices the datestring is returned like I want it to. On other devices the offset isn't calculated right and I receive the date and time from the input date-object. Can you give me some tips or advices? I guess my way off getting the default timezone does not work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

他不在意 2024-12-01 21:32:05
private String toGmtString(Date date){
    SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sd.setTimeZone(TimeZone.getTimeZone("GMT"));
    return sd.format(date);
}

您不需要创建新的 SimpleTimeZone,因为您并不是在发明一个新时区 - 您的程序中有 2 个现有时区,即 GMT 和默认时区。

您也不需要修改现有的日期对象,因为您不想表示不同的时间点 - 您只想以不同的方式显示相同的时间点。

您所需要做的就是告诉 SimpleDateFormat 在格式化时使用哪个时区。

private String toGmtString(Date date){
    SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sd.setTimeZone(TimeZone.getTimeZone("GMT"));
    return sd.format(date);
}

You don't need to create a new SimpleTimeZone, because you aren't inventing a new timezone - there are 2 existing timezones that come into play in your program, GMT and your default one.

You also don't need to modify your existing date object, because you don't want to represent a different point in time - you only want a different way to display the same point in time.

All you need to do is tell the SimpleDateFormat which timezone to use in formatting.

花开半夏魅人心 2024-12-01 21:32:05
private String toGmtString(Date date){
    //date formatter
    SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    //getting default timeZone
    TimeZone timeZone = TimeZone.getDefault();
    //getting current time
    Calendar cal = Calendar.getInstance()
    cal.setTime(date) ;
    //adding / substracting curren't timezone's offset
    cal.add(Calendar.MILLISECOND, -1 * timeZone.getRawOffset());    
    //formatting and returning string of date
    return sd.format(cal.getTime());
}
private String toGmtString(Date date){
    //date formatter
    SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    //getting default timeZone
    TimeZone timeZone = TimeZone.getDefault();
    //getting current time
    Calendar cal = Calendar.getInstance()
    cal.setTime(date) ;
    //adding / substracting curren't timezone's offset
    cal.add(Calendar.MILLISECOND, -1 * timeZone.getRawOffset());    
    //formatting and returning string of date
    return sd.format(cal.getTime());
}
梦魇绽荼蘼 2024-12-01 21:32:05

java.time

使用现代日期时间 API java.time,有多种方法可以实现:

  1. 解析为 LocalDateTime ➡️ 组合它与您的时区一起获取 ZonedDateTime ➡️ 转换为 Instant ➡️ 使用 ZonedDateTime href="https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html#atZone-java.time.ZoneId-" rel="nofollow noreferrer">即时# atZone 和 UTC 时区。
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2011-07-18 13:00:00";

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);

        LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);

        // Using ZoneId.of("Europe/Berlin") for the demo. Change it to
        // ZoneId.systemDefault()
        Instant instant = ldt.atZone(ZoneId.of("Europe/Berlin")).toInstant();

        ZonedDateTime zdtUtc = instant.atZone(ZoneId.of("Etc/UTC"));

        System.out.println(zdtUtc.format(dtf)); // 2011-07-18 11:00:00
    }
}
  1. 解析为 LocalDateTime ➡️ 将其与您的时区结合起来以获得 ZonedDateTime ➡️ 转换为 Instant ➡️ 使用 < 转换为 ZonedDateTime一个href="https://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html#ofInstant-java.time.Instant-java.time.ZoneId-" rel="nofollow noreferrer" >ZonedDateTime#ofInstant 和 UTC 时区。
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2011-07-18 13:00:00";

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);

        LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);

        // Using ZoneId.of("Europe/Berlin") for the demo. Change it to
        // ZoneId.systemDefault()
        Instant instant = ldt.atZone(ZoneId.of("Europe/Berlin")).toInstant();

        ZonedDateTime zdtUtc = ZonedDateTime.ofInstant(instant, ZoneId.of("Etc/UTC"));

        System.out.println(zdtUtc.format(dtf)); // 2011-07-18 11:00:00
    }
}
  1. 使用 ZonedDateTime#withZoneSameInstant
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2011-07-18 13:00:00";

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);

        LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);

        // Using ZoneId.of("Europe/Berlin") for the demo. Change it to
        // ZoneId.systemDefault()
        ZonedDateTime zdtPak = ldt.atZone(ZoneId.of("Europe/Berlin"));

        ZonedDateTime zdtUtc = zdtPak.withZoneSameInstant(ZoneId.of("Etc/UTC"));

        System.out.println(zdtUtc.format(dtf)); // 2011-07-18 11:00:00
    }
}
  1. 使用 <代码> DateTimeFormatter#withZoneZonedDateTime# withZoneSameInstant
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2011-07-18 13:00:00";

        // Using ZoneId.of("Europe/Berlin") for the demo. Change it to
        // ZoneId.systemDefault()
        DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("u-M-d H:m:s", Locale.ENGLISH)
                                        .withZone(ZoneId.of("Europe/Berlin"));

        ZonedDateTime zdtPak = ZonedDateTime.parse(strDateTime, dtfInput);

        ZonedDateTime zdtUtc = zdtPak.withZoneSameInstant(ZoneId.of("Etc/UTC"));

        DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
        System.out.println(zdtUtc.format(dtfOutput)); // 2011-07-18 11:00:00
    }
}

了解有关现代日期时间 API*< /sup> 来自跟踪:日期时间


* 无论出于何种原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport 将大部分 java.time 功能向后移植到 Java 6 和 Java 6 7. 如果您正在处理 Android 项目,并且您的 Android API 级别仍然不符合 Java-8,请检查 通过脱糖提供 Java 8+ API如何在Android项目中使用ThreeTenABP

java.time

Using java.time, the modern date-time API, there are many ways to do it:

  1. Parse to LocalDateTime ➡️ Combine it with your timezone to get ZonedDateTime ➡️ Convert to Instant ➡️ Convert to ZonedDateTime using Instant#atZone and UTC timezone.
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2011-07-18 13:00:00";

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);

        LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);

        // Using ZoneId.of("Europe/Berlin") for the demo. Change it to
        // ZoneId.systemDefault()
        Instant instant = ldt.atZone(ZoneId.of("Europe/Berlin")).toInstant();

        ZonedDateTime zdtUtc = instant.atZone(ZoneId.of("Etc/UTC"));

        System.out.println(zdtUtc.format(dtf)); // 2011-07-18 11:00:00
    }
}
  1. Parse to LocalDateTime ➡️ Combine it with your timezone to get ZonedDateTime ➡️ Convert to Instant ➡️ Convert to ZonedDateTime using ZonedDateTime#ofInstant and UTC timezone.
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2011-07-18 13:00:00";

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);

        LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);

        // Using ZoneId.of("Europe/Berlin") for the demo. Change it to
        // ZoneId.systemDefault()
        Instant instant = ldt.atZone(ZoneId.of("Europe/Berlin")).toInstant();

        ZonedDateTime zdtUtc = ZonedDateTime.ofInstant(instant, ZoneId.of("Etc/UTC"));

        System.out.println(zdtUtc.format(dtf)); // 2011-07-18 11:00:00
    }
}
  1. Using ZonedDateTime#withZoneSameInstant:
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2011-07-18 13:00:00";

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);

        LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);

        // Using ZoneId.of("Europe/Berlin") for the demo. Change it to
        // ZoneId.systemDefault()
        ZonedDateTime zdtPak = ldt.atZone(ZoneId.of("Europe/Berlin"));

        ZonedDateTime zdtUtc = zdtPak.withZoneSameInstant(ZoneId.of("Etc/UTC"));

        System.out.println(zdtUtc.format(dtf)); // 2011-07-18 11:00:00
    }
}
  1. Using DateTimeFormatter#withZone and ZonedDateTime#withZoneSameInstant:
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2011-07-18 13:00:00";

        // Using ZoneId.of("Europe/Berlin") for the demo. Change it to
        // ZoneId.systemDefault()
        DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("u-M-d H:m:s", Locale.ENGLISH)
                                        .withZone(ZoneId.of("Europe/Berlin"));

        ZonedDateTime zdtPak = ZonedDateTime.parse(strDateTime, dtfInput);

        ZonedDateTime zdtUtc = zdtPak.withZoneSameInstant(ZoneId.of("Etc/UTC"));

        DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
        System.out.println(zdtUtc.format(dtfOutput)); // 2011-07-18 11:00:00
    }
}

Learn more about the modern date-time API* from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文