2017-06-23 6 views
1

日付を解析するスレッドセーフな静的メソッドを使用してJavaクラスを作成したいと考えています。私は、Java 7以前の日付クラスのいくつかはスレッドセーフではないことを理解しています。この機能のJavaの8で最高のスレッドセーフな実装である何:テキストを解析するJava 8の最良の方法date to millisecond timestamp

public class DateUtil { 

    public static long getTimestamp(String text) { 
     DateFormat df = new SimpleDateFormat("M/d/yyyy"); 
     df.setTimeZone(TimeZone.getTimeZone("America/New_York")); 
     long timestamp = df.parse(text).getTime(); 
     return timestamp; 
    } 

} 

しかし、その代わりためDateFormatの新しいインスタンスを作成する:Javaの7以前で

String text = "5/16/2008"; 
long timestamp = DateUtil.getTimestamp(text); 

、あなたはこれを行うだろうすべての呼び出しで、このstatic getTimestampメソッドへのすべての呼び出しに対して1つの静的インスタンスを共有します。私はこれがスレッドセーフではないことを理解しています。

重要な要件の1つは、解析したいテキストがHH:mm:ss解像度のない「5/16/2008」のような短い日付を持つことです。

私は、Joda-Timeのような第三者のライブラリではなく、標準のJava 8クラスだけを使用したいと考えています。

+0

サードパーティのJoda-Timeライブラリは(ほとんど) 'java.time。*'パッケージの標準Java 8クラスになっています。 –

答えて

4

はここでスレッドセーフjava.text.SimpleDateFormatとは異なり、かつ不変であることがstatic finalフォーマッターインスタンスを使用するJava 8のjava.time.*パッケージを使用するようにリファクタリング、コードのバージョンです。

import java.time.LocalDate; 
import java.time.ZoneId; 
import java.time.format.DateTimeFormatter; 
import java.util.Date; 

public class DateUtil { 
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/d/yyyy"); 

    public static long getTimestamp(String text) { 
     LocalDate localDate = LocalDate.parse(text, formatter); 
     return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()).getTime(); 
    } 
} 
0

joda-time libを使用できます。 DateTimeは不変です。一度作成すると値は変更されないので、クラスは同期しなくても安全に渡して複数のスレッドで使用できます。
DateTimeに対するコンパニオンの可変クラスはMutableDateTimeであり、そのクラスは変更可能であり、スレッドセーフではありません。 DateTimeFormatt

DateTimeFormatter formatter = DateTimeFormat.forPattern("M/d/yyyy'T'HH:mm:ss.SSSZZ") 
    .withLocale(Locale.ROOT).withChronology(ISOChronology.getInstanceUTC()); 
DateTime dt = formatter.parseDateTime(text); 

参考:DatetimeFormat api

0

ck1の回答に記載されているように、java.time APIの使用法は、従来のクラスよりも優れたアプローチです。 DateTimeFormatterは不変でスレッドセーフで、静的な最終インスタンスを使用することで問題は解決します。 私がその答えと異なる部分はコードにあります。Dateのクラスを使って時刻を取得しています。私はここでもjava.timeのアプローチを採用したいと思います。以下は私のバージョンです:

public class DateUtil { 

    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/d/yyyy"); 

    public static long getTimestamp(String text) { 
     LocalDate localDate = LocalDate.parse(text, formatter); 
     return Instant.from(localDate.atStartOfDay(ZoneId.systemDefault())).toEpochMilli(); 
    } 

    public static void main(String[] args) { 
     String text = "5/16/2008"; 
     long timestamp = DateUtil.getTimestamp(text); 
     System.out.println(timestamp); 
    } 
} 
関連する問題