JavaでcurrentTimeMillisを日付に変換する方法は?


140

サーバーで生成された特定のログファイルにミリ秒があります。ログファイルが生成されたロケールもわかっています。問題は、ミリ秒を指定された形式の日付に変換することです。そのログの処理は、異なるタイムゾーンにあるサーバーで行われています。"SimpleDateFormat"プログラムへの変換中は、マシンの日付が取得されるため、フォーマットされた日付はサーバーの正しい時刻を表していません。これをエレガントに扱う方法はありますか?

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));

出力:

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

ロケールとタイムゾーンを混同しないでください。完全に分かれています。ロケールは、月と日の名前の人間の言語、および月、日などのパーツの順序などの文化的基準を決定します。タイムゾーンは、UTCからのオフセットと、夏時間などの異常を処理するためのルールです。
バジルブルク

ミリ秒数が1970-01-01T00:00:00Zからではなく、他の瞬間からのカウントであったという問題でしたか?
バジルブルク

参考までに、ひどい古い日時クラス(GregorianCalendarSimpleDateFormatなど)と優れたJoda -Timeライブラリの両方が、現在のjava.timeクラスに取って代わられました。
バジルブルク2018年

回答:


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);

それを機能させるには、カレンダーをファイナルとして設定する必要がありました。final Calendar calendar = Calendar.getInstance();
Victor Augusto

4
カレンダーオブジェクトは一般に非常に大きいと見なされるため、可能な場合は避けてください。Dateオブジェクトは、必要な機能を備えていることを前提として、より優れたものになります。"Date date = new Date(millis);" ユーザーAVDによる他の回答で提供されるのは、最良のルートになるでしょう:)
Dick Lucas

1
どういうわけか、1515436200000l私はとして得calendar.get(Calendar.MONTH))てい0ます!
Sajib Acharya、

以下のようなFYI、ひどく面倒な古い日付時刻クラスjava.util.Datejava.util.Calendarjava.text.SimpleDateFormat今のレガシーに取って代わられ、java.timeの Javaの8に、後に内蔵されたクラス。Oracleによるチュートリアル参照してください。
バジルブルク2018年

2
@SajibAcharya Calendar.MONTHのインスタンスは0から始まることに注意してください。私たちが知っているように、「実際の」月を取得するには1つ追加する必要があります。例:0 = 1月、1 = 2月、2 = 3月など
shagberg

256

java.util.Dateクラスを使用SimpleDateFormatして、をフォーマットすることができますDate

Date date=new Date(millis);

java.timeパッケージ(チュートリアル)-Java SE 8で導入されたDateTime API を使用できます。

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
はるかに効率的です。
チャドビンガム2014年

2
いいえ。のすべての方法java.util.Dateが減価償却されるわけではありません。(JDK8には改良された日付と時刻のAPIがありますjava.time
adatapost

1
@RafaelZeffa、 '' 'Date(long date)' ''コンストラクターは非推奨ではありません
Gugelhupf

Dateオブジェクトは、下位互換性のために提供されています。上記のようにカレンダーを使用することをお勧めします。
トンSnoei

2
以下のようなFYI、ひどく面倒な古い日付時刻クラスjava.util.Datejava.util.Calendarjava.text.SimpleDateFormat今のレガシーに取って代わられ、java.timeの Javaの8に、後に内蔵されたクラス。Oracleによるチュートリアル参照してください。
バジルブルク2018年

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.

細部

他の回答では、時代遅れのクラスまたは誤ったクラスを使用しています。

java.util.Date/.Calendarなどの古い日時クラスは避けてください。それらは設計が不十分で、混乱し、面倒であることが証明されています。

java.time

java.timeのフレームワークは、Java 8に組み込まれており、後で来ます。機能の多くは、Java 6および7にバックポートされ、さらにAndroidに適合していますジョーダタイムを作ったのと同じ人々の何人かによって作られました。

アンは、Instantタイムライン上の瞬間であるUTCの解像度を持つナノ秒。その時代は、UTCにおける1970年の最初の瞬間です。

入力データが1970-01-01T00:00:00Z(質問では不明)からのミリ秒数であるとすると、を簡単にインスタンス化できますInstant

Instant instant = Instant.ofEpochMilli( 1_322_018_752_992L );

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

Zその規格でISO 8601フォーマットされた文字列は、のために短いですZuluし、意味UTCを

適切なタイムゾーン名を使用してタイムゾーンを適用し、を取得しZonedDateTimeます。

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

この参照してくださいIdeOne.comでライブ実行コードを

Asia/Kolkata タイムゾーン?

あなたのコードがインドのタイムゾーンに影響していると思います。ここでAsia/Kolkataは、タイムゾーンに合わせて調整すると、レポートと同じ時刻が表示されます。08:55これは、UTC値より5時間半進んでいます03:25

2011-11-23T08:55:52.992 + 05:30 [アジア/コルカタ]

デフォルトゾーン

JVMの現在のデフォルトのタイムゾーンを適用できます。デフォルトは実行時にいつでも変更できることに注意してください。JVM内の任意のアプリの任意のスレッドの任意のコードは、現在のデフォルトを変更できます。重要な場合は、ユーザーに希望の/予想されるタイムゾーンを尋ねます。

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

java.time

java.timeのフレームワークは、Java 8に組み込まれており、後にされています。これらのクラスは面倒古い取って代わるレガシーのような日付時刻クラスをjava.util.DateCalendar、& SimpleDateFormat

ジョダタイムプロジェクトは、今でメンテナンスモードへの移行をアドバイスjava.timeのクラス。

詳細については、Oracleチュートリアルを参照してください。スタックオーバーフローで多くの例と説明を検索してください。仕様はJSR 310です。

JDBC 4.2以降に準拠するJDBCドライバーを使用すると、java.timeオブジェクトをデータベースと直接交換できます。文字列やjava.sql。*クラスは必要ありません。

java.timeクラスはどこで入手できますか?

  • Java SE 8 Java SE 9以降
    • 内蔵。
    • 実装がバンドルされた標準Java APIの一部。
    • Java 9では、いくつかのマイナーな機能と修正が追加されています。
  • Java SE 6および Java SE 7
    • java.time機能の多くは、ThreeTen-BackportでJava 6および7にバックポートされています。
  • アンドロイド
    • Androidの新しいバージョンには、java.timeクラスの実装がバンドルされています。
    • 以前のAndroidでは、ThreeTenABPプロジェクトはThreeTen-Backport(上記)を採用しています。ThreeTenABPの使用方法…を参照してください。

ThreeTen-エクストラプロジェクトでは、追加のクラスでjava.timeを拡張します。このプロジェクトは、java.timeに将来追加される可能性があることを証明する場です。あなたはここにいくつかの有用なクラスのような見つけることがIntervalYearWeekYearQuarter、および多くを


上記のおすすめのインスタントを、デバイス(スマートフォンなど)のデフォルトのローカルタイムゾーンに変換するのは簡単ですか?
AJW 2016

1
@AJWはい。を呼び出しZoneId.systemDefault()ます。回答の最後に追加された新しいセクションを参照してください。
バジルブルク

すばらしい、試してみる。
AJW 2016

14

これを行う最も簡単な方法は、Joda DateTimeクラスを使用して、ミリ秒単位のタイムスタンプと必要なDateTimeZoneの両方を指定することです。

組み込みのJava DateクラスとCalendarクラスを使用しないことを強くお勧めします。彼らはひどいです。


GorgianCalenderが機能しませんでした...なんらかの理由で、システムのデフォルトのタイムゾーンが使用されました。ジョーダは完璧に機能しました。
2011年

グレゴリオ暦で何か違うことができるかどうかサンプルコードを見てみましょう
Amit

1
FYI、ジョダタイムプロジェクトは、今でメンテナンスモードへの移行を専門家の意見、java.timeのクラス。Oracleによるチュートリアルを参照してください。
バジルブルク2018年

13

JVMの標準であるように、ミリス値が1970年1月1日GMT以降のミリ秒数である場合、それはタイムゾーンに依存しません。特定のタイムゾーンでフォーマットしたい場合は、それをGregorianCalendarオブジェクトに変換して、タイムゾーンを設定するだけです。その後、それをフォーマットする多くの方法があります。


1
これは、GregorianCalendarとJodaのサンプルコードです。Jodaでは正しい出力が得られますが、Gregorianでは正しく出力されません。calendar.setTimeInMillis(yourmilliseconds); DateTime jodaTime = new DateTime(yourmilliseconds、DateTimeZone.forTimeZone(TimeZone.getTimeZone( "US / Central"))); DateTimeFormatter parser1 = DateTimeFormat.forPattern( "yyyy-MM-dd HH:mm:ss、SSS");
2011年

カレンダオブジェクトにタイムゾーンを設定することは機能しませんでしたが、日付フォーマッタオブジェクトに設定することはできましたか?
ビル

DateTimeとDateTimeFormatterとは何ですか?
SweetWisherツノヴ

11

私の解決策

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

私はそれをこのようにします:

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

getDateInstance(int style)以下のパラメーターとともに使用することもできます。

DateFormat.SHORT

DateFormat.MEDIUM

DateFormat.LONG

DateFormat.FULL

DateFormat.DEFAULT



5

最も簡単な方法:

private String millisToDate(long millis){

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

}

2

以下は、ミリ秒から日付形式に日付を取得するための私の解決策です。このコードを実行するには、Joda Libraryを使用する必要があります。

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を試すことができます。

        Instant date = Instant.ofEpochMilli(1549362600000l);
        LocalDateTime utc = LocalDateTime.ofInstant(date, ZoneOffset.UTC);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.