CurrentTimeMillis'i Java'da bir tarihe nasıl dönüştürebilirim?


140

Sunucuda oluşturulan belirli günlük dosyasında milisaniye var, ben de günlük dosyasının oluşturulduğu yerel ayarı biliyorum, benim sorunum milisaniyeyi belirtilen formatta tarihe dönüştürmektir. Bu günlüğün işlenmesi, farklı saat dilimlerinde bulunan sunucuda gerçekleşiyor. "SimpleDateFormat" programına dönüştürülürken makinenin tarihini alır gibi biçimlendirilmiş tarih sunucunun doğru zamanını temsil etmez. Bunu zarif bir şekilde ele almanın bir yolu var mı?

long yourmilliseconds = 1322018752992l;
        //1322018752992-Nov 22, 2011 9:25:52 PM 

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS",Locale.US);

GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central"));
calendar.setTimeInMillis(yourmilliseconds);

System.out.println("GregorianCalendar -"+sdf.format(calendar.getTime()));

DateTime jodaTime = new DateTime(yourmilliseconds, 
                    DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central")));
DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss,SSS");

System.out.println("jodaTime "+parser1.print(jodaTime));

Çıktı:

Gregorian Calendar -2011-11-23 08:55:52,992
jodaTime 2011-11-22 21:25:52,992

Locale'i saat dilimiyle karıştırmayın. Tamamen ayrı. Yerel ayar, ay ve günlerin adı için insan dilini ve ay, gün vb. Gibi parçaların sırası gibi kültürel normları belirler. Bir saat dilimi UTC'den ofset artı Yaz Saati Uygulaması gibi anormalliklerin işlenmesine ilişkin kurallar ile dengelenir.
Basil Bourque

Milisaniye sayısının 1970-01-01T00: 00: 00Z'den değil, başka bir andan itibaren bir sayı olması sorunu muydu?
Basil Bourque

FYI, hem korkunç eski tarih-saat sınıfları ( GregorianCalendar, SimpleDateFormatvb.) Hem de mükemmel Joda-Time kütüphanesi artık modern java.time sınıfları ile desteklenmektedir.
Basil Bourque

Yanıtlar:


115
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeStamp);

int mYear = calendar.get(Calendar.YEAR);
int mMonth = calendar.get(Calendar.MONTH);
int mDay = calendar.get(Calendar.DAY_OF_MONTH);

Takvim'i çalışması için final olarak ayarlamam gerekiyordu. final Calendar calendar = Calendar.getInstance();
Victor Augusto

4
Takvim nesneleri genellikle oldukça büyük sayılır, bu nedenle mümkün olduğunca kaçınılmalıdır. Bir Date nesnesi, ihtiyacınız olan işlevselliğe sahip olduğunu varsayarak daha iyi olacaktır. "Tarih tarihi = yeni Tarih (milis);" kullanıcı tarafından verilen diğer yanıt AVD en iyi rota olacak :)
Dick Lucas

1
Bir şekilde, için 1515436200000l, ben alıyorum calendar.get(Calendar.MONTH))olarak 0!
Sajib Acharya

Bilginize gibi korkunç zahmetli eski tarih-saat sınıfları java.util.Date, java.util.Calendarve java.text.SimpleDateFormatşimdi mirası supplanted, java.time sonra Java 8 ve yerleşik sınıflara. Oracle'ın Öğreticisine bakın .
Basil Bourque

2
@SajibAcharya Calendar.MONTH için örneklerin 0'dan başladığını unutmayın; bildiğimiz gibi "gerçek" ayı almak için bir tane eklemeniz gerekir. Örnek: 0 = Ocak, 1 = Şubat, 2 = Mart, vb.
Shagberg

256

Sen kullanabilir java.util.Datesınıfını ve sonra kullanmak SimpleDateFormatbiçimlendirmek için Date.

Date date=new Date(millis);

Biz kullanabilirsiniz java.time Java SE 8 tanıtılan DateTime API'leri - paket (eğitim).

var instance = java.time.Instant.ofEpochMilli(millis);
var localDateTime = java.time.LocalDateTime
                        .ofInstant(instance, java.time.ZoneId.of("Asia/Kolkata"));
var zonedDateTime = java.time.ZonedDateTime
                            .ofInstant(instance,java.time.ZoneId.of("Asia/Kolkata"));

// Format the date

var formatter = java.time.format.DateTimeFormatter.ofPattern("u-M-d hh:mm:ss a O");
var string = zonedDateTime.format(formatter);

2
Çok daha verimli.
Chad Bingham

2
Hayır! Tüm yöntemler java.util.Dateamortismana tabi tutulmaz. (İyileştirilmiş Tarih ve Saat API'leri yılında JDK8 en Orada java.time)
adatapost

1
@RafaelZeffa, '' 'Tarih (uzun tarih)' '' yapıcı kullanımdan kaldırıldı
Gugelhupf

Date nesnesi geriye dönük uyumluluk için sağlanmıştır. Takvim'i yukarıda önerildiği gibi kullanın.
Ton Snoei

2
Bilginize gibi korkunç zahmetli eski tarih-saat sınıfları java.util.Date, java.util.Calendarve java.text.SimpleDateFormatşimdi mirası supplanted, java.time sonra Java 8 ve yerleşik sınıflara. Oracle'ın Öğreticisine bakın .
Basil Bourque

24

tl; Dr.

Instant.ofEpochMilli( 1_322_018_752_992L )     // Parse count of milliseconds-since-start-of-1970-UTC into an `Instant`.
       .atZone( ZoneId.of( "Africa/Tunis" ) )  // Assign a time zone to the `Instant` to produce a `ZonedDateTime` object.

ayrıntılar

Diğer cevaplar modası geçmiş veya yanlış sınıflar kullanır.

Java.util.Date/.Calendar gibi eski tarih-saat sınıflarından kaçının. Kötü tasarlanmış, kafa karıştırıcı ve zahmetli olduklarını kanıtladılar.

java.time

Java.time çerçevesi daha sonra Java 8 ve yerleşik olarak geliyor. İşlevlerin çoğu Java 6 ve 7'ye desteklenir ve Android'e uyarlanır . Joda-Time ile aynı milletten bazıları tarafından yapıldı .

Bir Instantde zaman çizelgesi üzerinde bir andır UTC çözünürlüğe sahip nanosaniye . Onun dönemi UTC'de 1970'in ilk anıdır.

Giriş verilerinizin 1970-01-01T00: 00: 00Z'den (Soruda net değil) milisaniye sayısı olduğunu varsayarsak, kolayca anlayabiliriz Instant.

Instant instant = Instant.ofEpochMilli( 1_322_018_752_992L );

instant.toString (): 2011-11-23T03: 25: 52.992Z

Bu Zstandart ISO 8601 biçimlendirilmiş dize UTC'nin kısaltmasıdır Zuluve UTC anlamına gelir .

Bir kullanarak bir zaman dilimini uygula uygun bir zaman dilimi adını bir olsun, ZonedDateTime.

ZoneId zoneId = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( zoneId );

IdeOne.com'da canlı olarak çalışan bu koda bakın .

Asia/Kolkata saat dilimi ?

Kodunuzu etkileyen bir Hindistan saat dilimi olduğunu tahmin ediyorum. Burada, Asia/Kolkatasaat dilimine ayarlamanın, rapor ettiğinizle aynı günün saatini oluşturduğunu görüyoruz 08:55. Bu, UTC değerimizin beş buçuk saat ilerisindedir 03:25.

2011-11-23T08: 55: 52,992 + 05: 30 [Asya / Kolkata]

Varsayılan bölge

JVM'nin geçerli varsayılan saat dilimini uygulayabilirsiniz . Varsayılan değerlerin çalışma sırasında herhangi bir anda değişebileceğini unutmayın . JVM içindeki herhangi bir uygulamanın herhangi bir iş parçacığındaki herhangi bir kod geçerli varsayılanı değiştirebilir. Önemliyse kullanıcıdan istenen / beklenen saat dilimini isteyin.

ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

Hakkında java.time

Java.time çerçevesi daha sonra Java 8 ve yerleşiktir. Bu sınıflar zahmetli eski yerini mirası gibi tarih-saat sınıfları java.util.Date, Calendar& SimpleDateFormat.

Artık bakım modunda olan Joda-Time projesi java.time sınıflarına geçişi tavsiye ediyor .

Daha fazla bilgi için Oracle Eğiticisine bakın . Ve birçok örnek ve açıklama için Stack Overflow'da arama yapın. Özellikler JSR 310 .

JDBC 4.2 veya sonraki bir sürümle uyumlu bir JDBC sürücüsü ile java.time alışverişi yapabilirsiniz nesnelerini doğrudan veritabanınızla değiştirebilirsiniz. Dizelere veya java.sql. * Sınıflarına gerek yoktur.

Java.time sınıflarını nereden edinebilirsiniz?

ThreeTen-Ekstra proje ek sınıfları ile java.time uzanır. Bu proje, java.time'a gelecekteki olası eklemeler için bir kanıt zeminidir. Burada bazı yararlı sınıfları gibi bulabilir Interval, YearWeek, YearQuarter, ve daha .


Yukarıda önerdiğiniz Anında Arama'yı bir cihazda varsayılan olan yerel saat dilimine (örneğin bir akıllı telefona) dönüştürmek kolay mıdır?
AJW

1
@AJW Evet. Arayın ZoneId.systemDefault(). Cevabımın sonuna eklenen yeni bölüme bakın.
Basil Bourque

Mükemmel, bir deneyeceğim.
AJW

14

Bunu yapmanın en kolay yolu Joda DateTime sınıfını kullanmaktır ve hem zaman damgasını milisaniye cinsinden hem de istediğiniz belirtmektir.

Yerleşik Java Tarih ve Takvim sınıflarından kaçınmanızı önemle tavsiye ederim; onlar korkunç.


GorgianCalender işe yaramadı ... herhangi bir nedenle sistemin varsayılan saat dilimini aldı. Joda mükemmel çalıştı.
Amit

Gregorian ile farklı bir şeyler yapabilirsek örnek koda bakalım
Amit

1
FYI, Joda-Time projesi şu anda bakım modunda ve java.time sınıflarına geçişi tavsiye ediyor . Oracle'ın Öğreticisine bakın .
Basil Bourque

13

Milis değeri, JVM için standart olduğu gibi, 1 Ocak 1970 GMT'den beri milis sayısı ise, bu zaman diliminden bağımsızdır. Belirli bir saat dilimi ile biçimlendirmek istiyorsanız, bunu bir GregorianCalendar nesnesine dönüştürebilir ve saat dilimini ayarlayabilirsiniz. Bundan sonra onu biçimlendirmenin çeşitli yolları vardır.


1
Bu GregorianCalendar ve Joda ile örnek kod, Joda ile doğru çıktı alıyorum ama Gregorian ile GregorianCalendar takvim = yeni GregorianCalendar (TimeZone.getTimeZone ("US / Central")); calendar.setTimeInMillis (yourmilliseconds); DateTime jodaTime = yeni DateTime (zaman milisaniye, DateTimeZone.forTimeZone (TimeZone.getTimeZone ("ABD / Merkez"))); DateTimeFormatter parser1 = DateTimeFormat.forPattern ("yyyy-AA-gg SS: dd: ss, SSS");
Amit

Takvim nesnesindeki saat dilimini ayarlamak işe yaramadı, ancak tarih biçimlendirici nesnesine ayarlamak mı?
Bill

DateTime ve DateTimeFormatter nedir ??
SweetWisher ツ

11

Çözümüm

public class CalendarUtils {

    public static String dateFormat = "dd-MM-yyyy hh:mm";
    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);

    public static String ConvertMilliSecondsToFormattedDate(String milliSeconds){
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(Long.parseLong(milliSeconds));
        return simpleDateFormat.format(calendar.getTime());
    }
}

6

Bunu şöyle yaparım:

static String formatDate(long dateInMillis) {
    Date date = new Date(dateInMillis);
    return DateFormat.getDateInstance().format(date);
}

getDateInstance(int style)Aşağıdaki parametrelerle de kullanabilirsiniz :

DateFormat.SHORT

DateFormat.MEDIUM

DateFormat.LONG

DateFormat.FULL

DateFormat.DEFAULT



5

En kolay yol:

private String millisToDate(long millis){

    return DateFormat.getDateInstance(DateFormat.SHORT).format(millis);
    //You can use DateFormat.LONG instead of SHORT

}

2

Aşağıda milisaniyeden tarih biçimine tarih almak için benim çözümüm. Bu kodu çalıştırmak için Joda Library'yi kullanmalısınız .

import java.util.GregorianCalendar;
import java.util.TimeZone;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class time {

    public static void main(String args[]){

        String str = "1431601084000";
        long geTime= Long.parseLong(str);
        GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central"));
        calendar.setTimeInMillis(geTime);
        DateTime jodaTime = new DateTime(geTime, 
               DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central")));
        DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd");
        System.out.println("Get Time : "+parser1.print(jodaTime));

   }
}

1

Java.time api'yi deneyebilirsiniz;

        Instant date = Instant.ofEpochMilli(1549362600000l);
        LocalDateTime utc = LocalDateTime.ofInstant(date, ZoneOffset.UTC);
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.