web-dev-qa-db-ja.com

日付からの現地時間

DateインスタンスをLocalTimeインスタンスに変換しようとしています。

// Create the Date
Date date = format.parse("2011-02-18 05:00:00.0");    

// Convert to Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);

// Convert Calendar to LocalTime
Instant instant = Instant.ofEpochMilli(cal.getTimeInMillis());
LocalTime convert = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).toLocalTime();

コンパイラエラーは発生しませんが、LocalTimeインスタンスの値が間違っています。

Datefasttimeではなくcdateに時間を保存するため、機能しないと思います。

JDKバージョン1.8を使用しています。

12
Stanko

入力は実質的にLocalDateTimeです。それを単にLocalDateTimeに解析してからLocalTimeを取得する方がはるかに簡単です。心配するタイムゾーンはなく、レガシークラスはありません(DateCalendarは可能な限り避けてください...)

import Java.time.*;
import Java.time.format.*;
import Java.util.*;

public class Test {

    public static void main(String[] args) {
        DateTimeFormatter formatter =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S", Locale.US);

        String text = "2011-02-18 05:00:00.0";
        LocalDateTime localDateTime = LocalDateTime.parse(text, formatter);
        LocalTime localTime = localDateTime.toLocalTime();
        System.out.println(localTime);
    }
}
10
Jon Skeet

これも非常に簡単です:LocalTime time = LocalDateTime.ofInstant(new Date().toInstant(), ZoneId.systemDefault()).toLocalTime()

13
johanwannheden

Jon Skeetによる accepted Answer は正しいです。この回答はそれらのアイデアを拡張したものです。

従来の日時クラスを避ける

他のいくつかの回答と質問は、古いレガシー日時クラスを新しいものと混合しています。それは不必要で悪い習慣です。 Java.time クラスの要点は、厄介で混乱する古いクラスをreplaceすることです。

  • あなたがするしないJava.util.Date
  • あなたがするしないJava.util.Calendar

LocalDateTime

入力文字列に、UTCからのオフセットまたはタイムゾーンに関する情報が不足しています。したがって、 LocalDateTime オブジェクトとして解析します。

解析するには、真ん中のスペースをTに置き換えて、日時形式の ISO 8601 標準に準拠します。

String input = "2011-02-18 05:00:00.0".replace( " " , "T" );
LocalDateTime ldt = LocalDateTime.parse( input );

LocalTime

日付なしの時刻に集中するには、 LocalTime を要求します。

LocalTime lt = ldt.toLocalTime();

ZonedDateTime

これは実際の瞬間ではなく、タイムライン上のポイントではないことに注意してください。 UTCからのオフセットまたはタイムゾーンのコンテキストがない場合、ニュージーランドのオークランドで5 AM、コルカタで5 AM、パリで5 AM、またはモントリオールケベックで5 AMのどちらを意味しているかはわかりません。それらのそれぞれは、時間の非常に異なる瞬間になります。

コンテキストによって、意図したタイムゾーンが確かにわかっている場合は、それを適用します。 ZoneId を適用して ZonedDateTime を取得します。

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( z );

そこから、必要に応じてLocalTimeを要求します。

LocalTime lt = zdt.toLocalTime(); 

Instant

同じ瞬間を [〜#〜] utc [〜#〜] で表示したい場合は、Instantを抽出します。 Instant クラスは、 [〜#〜] utc [〜#〜] のタイムライン上の瞬間を表し、 ナノ秒 の分解能(小数部の最大9桁)。

一般に、ビジネスロジック、ロギング、データストレージ、およびデータ交換の多くで、 [〜#〜] utc [〜#〜] に焦点を合わせるのが最善です。 UTCを「1つの真の時間」と考えることを学びます。

Instant instant = zdt.toInstant();  // Same moment, shifted to UTC.
3
Basil Bourque

これを試して

    String datestring = "2011-02-18 05:00:00.0";
    SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");//take a look at MM
    Date date = dt.parse(datestring );
    Instant instant = Instant.ofEpochMilli(date.getTime());
    LocalTime res = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).toLocalTime();
0
user4624062