UTC'de LocalDateTime'ı LocalDateTime'a dönüştürme


86

LocalDateTime'ı UTC'de LocalDateTime'a dönüştürün.

LocalDateTime convertToUtc(LocalDateTime date) {

    //do conversion

}

Net üzerinden aradım. Ama bir çözüm bulamadım


4
LocalDateTime için javadoc'u buldunuz mu? Şöyle diyor: "Bu sınıf bir saat dilimini saklamıyor veya temsil etmiyor. Bunun yerine, doğum günleri için kullanılan tarihin bir duvar saatinde görülen yerel saatle birleştirilen bir açıklamasıdır. uzaklık veya saat dilimi gibi ek bilgiler olmadan zaman çizgisi. "
aro_tech

1
Sorunuz bir anlam ifade etmiyor - bu yöntemin içeriğini ve neyi başarmaya çalıştığınızı açıklamalısınız. API'nin çeşitli sınıflarının neyi temsil ettiğine dair temel bir yanlış anlamanız var gibi görünüyor.
asylias

3
Saat dilimlerini önemsiyorsanız, ZoneSameLocal () ve withZoneSameInstant () ile saat dilimleri arasında dönüştürme yöntemleri olan ZonedDateTime kullanmanız gerekir
JodaStephen

Ya. Anladım. Teşekkürler
Sarika.S

Yanıtlar:


105

Şahsen tercih ederim

LocalDateTime.now(ZoneOffset.UTC);

en okunabilir seçenek olduğu için.


26
Bu (şimdi) yeni bir zaman yaratmıyor mu? Asıl soru, bilinen bir saati UTC'ye dönüştürmekle
ilgiliydi

LocalDateTime'dan UTC -7: 00'a nasıl dönüşebiliriz
Ashok kumar Ganesan

74

Daha da basit bir yol var

LocalDateTime.now(Clock.systemUTC())

26
Güzel, ama asıl soruya cevap vermiyor.
eirlar

3
Bu cevap bir UTC tarihini LocalDate'e dönüştürür. Asıl soru, LocalDate'in UTC Tarihine nasıl dönüştürüleceğiydi.
Cypress Frankenfeld

LocalDateTime'dan UTC -7: 00'a nasıl dönüşebiliriz
Ashok kumar Ganesan

65

LocalDateTime, Bölge bilgilerini içermez. ZonedDatetime yapar.

LocalDateTime'ı UTC'ye dönüştürmek istiyorsanız, ZonedDateTime yumrukla kaydırmanız gerekir.

Aşağıdaki gibi dönüştürebilirsiniz.

LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt.toLocalTime());

ZonedDateTime ldtZoned = ldt.atZone(ZoneId.systemDefault());

ZonedDateTime utcZoned = ldtZoned.withZoneSameInstant(ZoneId.of("UTC"));

System.out.println(utcZoned.toLocalTime());

2
Teknik olarak paketlenmemiş olsa da bu doğrudur. ldt.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneId.of("UTC"))kısa ve öz, bölgeli örnek değişkenine ihtiyaç duyulmaması için hala yeterli anlam taşır.
Brett Ryan

22
ZoneOffset.UTCyerineZoneI‌​d.of("UTC")
ycomp

2
UTC OffsetDateTimeiçin daha uygundur ZonedDateTime. Kullanın: OffsetDateTime.now( ZoneOffset.UTC )veyamyInstant.atOffset( ZoneOffset.UTC )
Basil Bourque

15

Aşağıdakileri kullanın. Yerel tarih saatini alır ve saat dilimini kullanarak UTC'ye dönüştürür. İşlev oluşturmanıza gerek yoktur.

ZonedDateTime nowUTC = ZonedDateTime.now(ZoneOffset.UTC);
System.out.println(nowUTC.toString());

ZonedDateTime'ın LocalDateTime bölümünü almanız gerekiyorsa, aşağıdakileri kullanabilirsiniz.

nowUTC.toLocalDateTime();

Bir datetime sütununa UTC_TIMESTAMP varsayılan değerini ekleyemediğim için uygulamamda mysql'de UTC saatini eklemek için kullandığım statik bir yöntem .

public static LocalDateTime getLocalDateTimeInUTC(){
    ZonedDateTime nowUTC = ZonedDateTime.now(ZoneOffset.UTC);

    return nowUTC.toLocalDateTime();
}

14

İşte yerel tarih saatlerini bölgeden bölgeye dönüştürmek için kullanabileceğiniz basit bir küçük yardımcı program sınıfı, yerel bir tarih saatini doğrudan geçerli bölgeden UTC'ye dönüştürmek için bir yardımcı program (ana yöntemle çalıştırabilir ve sonuçları görebilirsiniz) basit bir testin):

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public final class DateTimeUtil {
    private DateTimeUtil() {
        super();
    }

    public static void main(final String... args) {
        final LocalDateTime now = LocalDateTime.now();
        final LocalDateTime utc = DateTimeUtil.toUtc(now);

        System.out.println("Now: " + now);
        System.out.println("UTC: " + utc);
    }

    public static LocalDateTime toZone(final LocalDateTime time, final ZoneId fromZone, final ZoneId toZone) {
        final ZonedDateTime zonedtime = time.atZone(fromZone);
        final ZonedDateTime converted = zonedtime.withZoneSameInstant(toZone);
        return converted.toLocalDateTime();
    }

    public static LocalDateTime toZone(final LocalDateTime time, final ZoneId toZone) {
        return DateTimeUtil.toZone(time, ZoneId.systemDefault(), toZone);
    }

    public static LocalDateTime toUtc(final LocalDateTime time, final ZoneId fromZone) {
        return DateTimeUtil.toZone(time, fromZone, ZoneOffset.UTC);
    }

    public static LocalDateTime toUtc(final LocalDateTime time) {
        return DateTimeUtil.toUtc(time, ZoneId.systemDefault());
    }
}

Ayrıca şunu ekleyin: final LocalDateTime backToLocal = DateTimeUtil.toZone (utc, ZoneOffset.UTC, ZoneId.systemDefault ()); System.out.println ("Yerel'e Dön:" + backToLocal);
rjdkolb

9

Soru?

Cevaplara ve soruya bakıldığında, soru önemli ölçüde değiştirilmiş gibi görünüyor. Şu anki soruyu cevaplamak için:

LocalDateTime'ı UTC'de LocalDateTime'a dönüştürün.

Saat dilimi?

LocalDateTimesaat dilimi hakkında herhangi bir bilgi depolamaz, sadece temelde yıl, ay, gün, saat, dakika, saniye ve daha küçük birimlerin değerlerini tutar. Öyleyse önemli bir soru şudur: Orijinalin saat dilimi nedir LocalDateTime? Zaten UTC de olabilir, bu nedenle dönüştürme yapılmasına gerek yoktur.

Sistem Varsayılan Saat Dilimi

Soruyu yine de sorduğunuzu düşünürsek, muhtemelen orijinal saatin sistem varsayılan saat diliminizde olduğunu ve bunu UTC'ye dönüştürmek istediğinizi kastettiniz. Çünkü genellikle bir LocalDateTimenesne, LocalDateTime.now()sistemin varsayılan saat diliminde geçerli saati döndüren kullanılarak oluşturulur . Bu durumda, dönüşüm aşağıdaki gibi olacaktır:

LocalDateTime convertToUtc(LocalDateTime time) {
    return time.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
}

Dönüşüm sürecine bir örnek:

2019-02-25 11:39 // [time] original LocalDateTime without a timezone
2019-02-25 11:39 GMT+1 // [atZone] converted to ZonedDateTime (system timezone is Madrid)
2019-02-25 10:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2019-02-25 10:39 // [toLocalDateTime] losing the timezone information

Açık Saat Dilimi

Diğer herhangi bir durumda, dönüştürülecek zamanın saat dilimini açıkça belirttiğinizde, dönüşüm aşağıdaki gibi olacaktır:

LocalDateTime convertToUtc(LocalDateTime time, ZoneId zone) {
    return time.atZone(zone).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
}

Dönüşüm sürecine bir örnek:

2019-02-25 11:39 // [time] original LocalDateTime without a timezone
2019-02-25 11:39 GMT+2 // [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)
2019-02-25 09:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2019-02-25 09:39 // [toLocalDateTime] losing the timezone information

atZone()Yöntem

atZone()Yöntemin sonucu, gün ışığından yararlanma saati (DST) de dahil olmak üzere saat diliminin tüm kurallarını dikkate aldığından bağımsız değişken olarak geçen süreye bağlıdır. Örneklerde zaman 25 Şubat idi, Avrupa'da bu kış saati anlamına geliyor (DST yok).

Farklı bir tarih kullanacak olsaydık, geçen yıldan 25 Ağustos diyelim, DST'ye göre sonuç farklı olurdu:

2018-08-25 11:39 // [time] original LocalDateTime without a timezone
2018-08-25 11:39 GMT+3 // [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)
2018-08-25 08:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2018-08-25 08:39 // [toLocalDateTime] losing the timezone information

GMT saati değişmez. Bu nedenle diğer saat dilimlerindeki uzaklıklar ayarlanır. Bu örnekte, Estonya'nın yaz saati GMT + 3 ve kış saati GMT + 2'dir.

Ayrıca, saatleri bir saat geri değiştirme geçişi içinde bir zaman belirtirseniz. Örneğin, 28 Ekim 2018 03:30, Estonya için bu iki farklı zaman anlamına gelebilir:

2018-10-28 03:30 GMT+3 // summer time [UTC 2018-10-28 00:30]
2018-10-28 04:00 GMT+3 // clocks are turned back 1 hour [UTC 2018-10-28 01:00]
2018-10-28 03:00 GMT+2 // same as above [UTC 2018-10-28 01:00]
2018-10-28 03:30 GMT+2 // winter time [UTC 2018-10-28 01:30]

Farkı manuel olarak belirtmeden (GMT + 2 veya GMT + 3), 03:30saat dilimi için saat Europe/Tallinniki farklı UTC zamanı ve iki farklı fark anlamına gelebilir.

Özet

Gördüğünüz gibi, sonuç, argüman olarak geçen zamanın zaman dilimine bağlıdır. Saat dilimi LocalDateTimenesneden çıkarılamadığından, onu UTC'ye dönüştürmek için hangi saat diliminden geldiğini kendiniz bilmeniz gerekir.


1
LocalDateTime hakkındaki bilgiler için teşekkürler, saat dilimi hakkında hiçbir bilgi saklamıyor! LocalDateTime does not store any information about the time-zone, it just basically holds the values of year, month, day, hour, minute, second, and smaller units.
LiuWenbin_NO.

5

tldr: Bunu yapmanın bir yolu yok; Bunu yapmaya çalışıyorsanız, LocalDateTime yanlış anlıyorsunuz .

Nedeni, LocalDateTime örnekler oluşturulduktan sonra Saat Dilimini kaydetmemesidir. Saat dilimi olmayan bir tarihi, belirli bir saat dilimine dayalı olarak başka bir tarih saatine dönüştüremezsiniz.

Nitekim, amacınız rastgele sonuçlar elde etmiyorsa , LocalDateTime.now () asla üretim kodunda çağrılmamalıdır. Bunun gibi bir LocalDateTime örneği oluşturduğunuzda, bu örnek YALNIZCA geçerli sunucunun saat dilimine dayalı olarak tarih saati içerir; bu, bu kod parçasının farklı bir saat dilimi yapılandırmasına sahip bir sunucu çalıştırması durumunda farklı bir sonuç üreteceği anlamına gelir.

LocalDateTime , tarih hesaplamayı basitleştirebilir. Evrensel olarak kullanılabilir gerçek bir veri zamanı istiyorsanız, ZonedDateTime veya OffsetDateTime kullanın: https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html .


LocalDateTime, Saat Dilimini kaydetmez, ancak bu bilgiye başka bir yerden sahip olabilirsiniz ve bu bilgileri dönüştürme işleminden önce LocalDateTimes'ınıza ekleyebilirsiniz.
Tristan

1

Bu yöntemi kullanarak bunu deneyin.

senin dönüştürmek LocalDateTimeTo ZonedDateTimekullanarak bir yöntem ve sistem varsayılan saat dilimini iletebilir veya kullanabilirsiniz BölgeKimliği gibi bölgeninZoneId.of("Australia/Sydney");

LocalDateTime convertToUtc(LocalDateTime dateTime) {
  ZonedDateTime dateTimeInMyZone = ZonedDateTime.
                                        of(dateTime, ZoneId.systemDefault());

  return dateTimeInMyZone
                  .withZoneSameInstant(ZoneOffset.UTC)
                  .toLocalDateTime();
  
}

Bölgenize geri dönmek için yerel tarih saati kullanın:

LocalDateTime convertFromUtc(LocalDateTime utcDateTime){
    return ZonedDateTime.
            of(utcDateTime, ZoneId.of("UTC"))
            .toOffsetDateTime()
            .atZoneSameInstant(ZoneId.systemDefault())
            .toLocalDateTime();
}

-1

böyle bir şey yapan bir yardımcı uygulayabilirsiniz:

public static LocalDateTime convertUTCFRtoUTCZ(LocalDateTime dateTime) {
    ZoneId fr = ZoneId.of("Europe/Paris");
    ZoneId utcZ = ZoneId.of("Z");
    ZonedDateTime frZonedTime = ZonedDateTime.of(dateTime, fr);
    ZonedDateTime utcZonedTime = frZonedTime.withZoneSameInstant(utcZ);
    return utcZonedTime.toLocalDateTime();
}

UTC fr'den UTC Z'ye? hiçbir şey ifade etmiyor. UTC = Z, UTC <> fr
Tristan

-2
public static String convertFromGmtToLocal(String gmtDtStr, String dtFormat, TimeZone lclTimeZone) throws Exception{
        if (gmtDtStr == null || gmtDtStr.trim().equals("")) return null;
        SimpleDateFormat format = new SimpleDateFormat(dtFormat);
        format.setTimeZone(getGMTTimeZone());
        Date dt = format.parse(gmtDtStr);
        format.setTimeZone(lclTimeZone);
        return

format.format (dt); }


1
Lütfen gençlere uzun zamandır modası geçmiş ve herkesin bildiği gibi sorunlu SimpleDateFormatsınıfı kullanmayı öğretmeyin . En azından ilk seçenek olarak değil. Ve herhangi bir çekincesiz değil. Bugün java.time, modern Java tarih ve saat API'sinde ve onun DateTimeFormatter.
Ole VV
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.