Milisaniye cinsinden uzun bir dönemden nasıl Java 8 LocalDate oluşturabilirim?


218

longEpoch başlangıcından bu yana milisaniye olarak temsil edilen tarihleri s olarak döndüren harici bir API var .

Eski stil Java API ile, basitçe Dateondan bir

Date myDate = new Date(startDateLong)

Java 8'in LocalDate/ LocalDateTimesınıflarının eşdeğeri nedir ?

Geçerli yerel saat diliminde longbir ile temsil edilen noktayı dönüştürmekle ilgileniyorum LocalDate.


6
Peki hangi saat dilimine önem verdiğinizi düşünerek başlamalısınız. "Dönemden bu yana geçen milisaniye" değeri size farklı bir zaman dilimindeki farklı tarihleri ​​gösterebilecek bir an ... verir. java.util.DateAsla gerçekten böyle bir tarih olmadığını aklınızda bulundurun LocalDate- zaman içinde de bir an oldu.
Jon Skeet

2
: Bu soruyu kontrol stackoverflow.com/questions/21242110/... , dönüşümünü kapsayan java.util.DateiçineLocalDate
hotzst

3
Not: Bu Soru ve Cevap, File.lastModified()(milisaniyeyi) dönüştürmeye çalışanlar için de değerlidir LocalDate(Time).
kevinarpe

Yanıtlar:


403

Dönemden bu yana milisaniyeniz varsa ve geçerli yerel saat dilimini kullanarak bunları yerel bir tarihe dönüştürmek istiyorsanız,

LocalDate date =
    Instant.ofEpochMilli(longValue).atZone(ZoneId.systemDefault()).toLocalDate();

ancak sistemin varsayılan saat diliminin bile değişebileceğini, dolayısıyla aynı longdeğerin aynı makinede bile sonraki çalışmalarda farklı sonuçlar üretebileceğini unutmayın.

Ayrıca, LocalDateaksine java.util.Date, gerçekten bir tarihi ve saati değil, bir tarihi temsil ettiğini unutmayın .

Aksi takdirde aşağıdakileri kullanabilirsiniz LocalDateTime:

LocalDateTime date =
    LocalDateTime.ofInstant(Instant.ofEpochMilli(longValue), ZoneId.systemDefault());

2
Daha ayrıntılı bir açıklama için benden +1. Bu arada, sistem dışı bir bölge bile (tzupdater-tool veya jdk-change ile) değişebilir ve böylece önce ve sonra farklı sonuçlar üretebilir.
Meno Hochschild

2
@Meno Hochschild: Sabit kodlu zaman dilimlerine odaklanmıyordum, daha çok kullanıcı tarafından belirtilen zaman dilimlerine kıyasla, programcının doğal olarak değişebileceğini varsaydığı bir yapılandırma dosyasından veya ortam değişkenlerinden okuyordum. Sabit kodlu zaman dilimleri sistem varsayılanı gibidir; programcı asla değişmediklerini düşünmeye
Holger

2
@Demigod LocalDateTime.ofEpochSecond(…)bir gerçek gerektirir ZoneOffset, ancak a ZoneId.systemDefault()döndürür ZoneId. A ZoneId, başvurduğunuz zamana bağlı olarak farklı ofsetlerle eşleşebilir. Yani ne LocalDateTime.ofInstantbelirtilen dönüştürme, sende olduğu ZoneIdsağlanan göre Instant.
Holger

2
Epoch UTC olarak tanımlanır ve bu nedenle saat diliminden bağımsız olmalıdır, bu nedenle ZoneId her zaman UTC olmalıdır.
PlexQ

2
@PlexQ saat dilimi gerçekten zaman dilimi bağımsızdır Epoch'tan için alakalı değil, ama ortaya çıkan semantik için belirtilen LocalDateveya LocalDateTime. Bu sonuç nesnelerinin sonraki kullanımıyla tutarlı olduğu sürece istediğiniz herhangi bir saat dilimini belirtebilirsiniz. Farklı yöntemlerle oluşturulan birden çok nesne ile uğraşırken neler olduğunu düşünün. Yerel tarih veya günler için tipik kullanım durumları , sistemin varsayılan saat dilimini içerir, örneğin LocalDateTime.now()LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()), ZoneId.systemDefault())
Holger

37

Instant.ofEpochMilli (uzun) ile başlayabilirsiniz :

LocalDate date =
  Instant.ofEpochMilli(startDateLong)
  .atZone(ZoneId.systemDefault())
  .toLocalDate();

5
Saat dilimi hakkında açık olduğu için +1. Atlanırsa, JVM'nin geçerli varsayılan saat dilimi, tarihin belirlenmesinde dolaylı olarak uygulanır. Herhangi bir an için, tarih doğudan yeni bir gün geçtikçe tarih dünyanın her yerine göre değişir.
Basil Bourque

12

Sanırım daha iyi bir cevabım var.

new Timestamp(longEpochTime).toLocalDateTime();

Yeni Zaman Damgası (ts) .toLocalDateTime (). toLocalDate ()
Stepan Yakovenko

5
Yani - javal.sql.Timestamp'ı içe aktarmanın sakıncası yoksa, Java'nın monolitik doğası göz önüne alındığında iyi olduğunu düşünüyorum çünkü JVM'nin sadece bir parçası ... ama biraz daha kötü kokuyor, ama yine de daha iyi o çağın temelde UTC olduğunu kabul etti.
PlexQ

1
TimestampSınıf kötü tasarlanmış ve uzun modası geçmiş olduğunu. Kodunuz JVM'nin saat dilimi ayarını kullanacaktır, ancak bu ayar programınızın başka bir bölümü veya aynı JVM'de çalışan başka bir program tarafından değiştirilebildiğinden, ne olduğundan emin olamayız.
Ole VV

1
Hangi saat diliminin kullanıldığının açık olması her zaman daha iyidir. Eski java.sql.Timestamp'ı kullanmak, sistem saat diliminin örtülü olarak uygulanmasının dezavantajına sahiptir ve bu da genellikle geliştiriciler arasında karışıklığa neden olur.
Ruslan

3

Zaman dilimleri ve şeyler bir yana, çok basit bir alternatif new Date(startDateLong)olabilirLocalDate.ofEpochDay(startDateLong / 86400000L)


6
En azından 86400000L'nin ne anlama geldiğini açıklamanız gerektiğini düşünüyorum.
BAERUS

3
Bir gün içindeki milisaniye sayısını tespit etmenin çok kolay olduğunu düşündüm.
Michael Piefel

7
Bazıları için, ve ben sadece bunun mantıklı olacağını düşündüm, ama yeniden hesaplama olmadan bir günde kaç ms gerçekten, emin olmazdım. Sadece kendim için konuşursak, bu sayıyı o kadar iyi bilmiyorum ki ne anlama geldiğini otomatik olarak biliyorum.
BAERUS

Ayrıca kabul edilen cevabın gerçekten en iyi cevap olduğunu unutmayın, sadece ezici görünüyor. Benim basit kesmek sadece benim birçok durumda yeterli olmak. Joda'nın yaptığı gibi java.timeiçermeyen yazık DateTimeConstants.
Michael Piefel

2
java.util.concurrent.TimeUnit.MILLISECONDS.toDays(startDateLong)
Vadzim

1

now.getTime () öğesini uzun değerinizle değiştirin.

//GET UTC time for current date
        Date now= new Date();
        //LocalDateTime utcDateTimeForCurrentDateTime = Instant.ofEpochMilli(now.getTime()).atZone(ZoneId.of("UTC")).toLocalDateTime();
        LocalDate localDate = Instant.ofEpochMilli(now.getTime()).atZone(ZoneId.of("UTC")).toLocalDate();
        DateTimeFormatter dTF2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        System.out.println(" formats as " + dTF2.format(utcDateTimeForCurrentDateTime));

-6

Dönem saniye zaman damganızın SQL'den geldiği veya bir şekilde SQL ile ilişkili olduğu belirli bir durumda, bunu şöyle elde edebilirsiniz:

long startDateLong = <...>

LocalDate theDate = new java.sql.Date(startDateLong).toLocalDate();

2
Bu gerçekten sorulan soru ile pek alakalı değil
Ketan R

@KetanR, katılmıyorum. Soru "nasıl LocalDatealınır epoch-millis" ve nasıl java.sql.Datesteno için kullanarak göstereceğim . Bu yaklaşım, zaten bazı kapasitelerde JDBC ile uğraşan kodda anlamlıdır ve gayet iyi çalışır. Hala ikna olmamışsanız, bunun ilk soru ile nasıl ilişkili olmadığını açıklayın.
M. Prokhorov

2
Soruyu okursanız, "tarihleri ​​uzun süre döndüren harici API" yazıyor ve SQL'den uzun bir tarih alıyorsanız bu dönüşümün nasıl yapılabileceğini açıklıyorsunuz. Cevabınız, tarih dönüşümünün çok özel bir vakasını açıklıyor, ancak sorulan soru ile gerçekten ilgili değil.Açıklamanız, ilgili diğer sorulara geçerli bir cevap olabilir.
Ketan R

@KetanR, SQL'den uzun bir tarih alırsa, şemasını değiştirmenizi tavsiye ederim, böylece artık bu formdaki tarihleri ​​almaz. Ancak, biri başka bir yerden (harici API) milis-zaman damgası olarak tarih alırsa ve JDBC sorguları yapmak için hemen bu tarihleri ​​kullanırsa, java.sql.Dateyaklaşım mevcut olan en kısa, kod-bilge arasındadır ve bunların hepsi bu kadar yararlı olmadığını söyleyebilirim Instantsonuç aynı olduğunda tüm ara geçiş nesnelerine gitmek .
M. Prokhorov

2
Daha önce de söylediğim gibi ve en son açıklamanızdan da anlaşılacağı gibi, cevabınız doğru ama eldeki soru için değil Soru şöyle diyor: "Uzun zamandır temsil edilen noktayı geçerli yerel saat dilimimde bir LocalDate'e dönüştürmekle ilgileniyorum. "cevabınız şunu söylüyor:" tarihleri ​​milis-zaman damgası olarak alın ve hemen bu tarihleri ​​JDBC sorguları yapmak için kullanın ". Burada net olmayan ne anlamadım?
Ketan R
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.