私が新しいDate
オブジェクトを作成するとき、それは現在の時間に初期化されますが、現地の時間帯です。 GMTで現在の日時を取得する方法を教えてください。
Java.util.Date
には特定の時間帯はありませんが、その値はUTCに関して最も一般的に考えられています。現地時間だと思うのはどうしてですか。
正確に言うと、Java.util.Date
内の値は、1970年1月1日午前0時(UTC)に発生したUNIXエポック以降のミリ秒数です。同じエポックを他のタイムゾーンで記述することもできますが、伝統的な記述はUTCに関するものです。固定エポックから数ミリ秒なので、Java.util.Date
内の値は、現地のタイムゾーンに関係なく、特定の時点で世界中で同じです。
問題は、ローカルタイムゾーンを使用するCalendarのインスタンス、またはローカルタイムゾーンも使用するDate.toString()
、またはデフォルトでローカルタイムゾーンも使用するSimpleDateFormat
インスタンスを使用して表示していることにあります。
これが問題にならない場合は、いくつかのサンプルコードを投稿してください。
しかし、 Joda-Time を使用することをお勧めします。これは、より明確なAPIを提供します。
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
//Local time zone
SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
//Time in GMT
return dateFormatLocal.parse( dateFormatGmt.format(new Date()) );
Instant.now() // Capture the current moment in UTC.
その値を表す文字列を生成します。
Instant.now().toString()
2016-09-13T23:30:52.123Z
Jon Skeetによる正解 が述べたように、Java.util.Dateオブジェクトにはタイムゾーンがありません†。ただし、その toString
実装は、その日時値の文字列表現を生成するときにJVMのデフォルトのタイムゾーンを適用します。ナイーブプログラマにとって混乱させるのは、Date seemsがタイムゾーンを持つことですが、そうではありません。
JavaにバンドルされているJava.util.Date
、j.u.Calendar
、およびJava.text.SimpleDateFormat
クラスは厄介なことで有名です。 それらを避けてください。代わりに、これらの適切な日時ライブラリのいずれかを使用します。
Java 8 は、古いJava.util.Date/Calendarクラスに取って代わる優れた新しい Java.time。*パッケージ をもたらします。
UTC/GMTで現在の時刻を取得するのは、簡単な1行の…
Instant instant = Instant.now();
その Instant
クラスはJava.timeの基本的な構成要素であり、 ナノ秒 の解像度で UTC のタイムライン上の瞬間を表します。
Java 8では、現在の瞬間が最大ミリ秒の解像度でキャプチャされます。 Java 9は新しい実装をもたらします of Clock
は、ホストコンピューターのクロックハードウェアの能力に応じて、このクラスの最大ナノ秒能力までの現在の瞬間をキャプチャします。
toString
メソッドは、 特定のISO 8601形式 を使用して、その値の文字列表現を生成します。その形式は、秒の端数を表すために必要に応じて、0、3、6、または9桁の数字( ミリ秒 、 マイクロ秒 、または ナノ秒 )を出力します。
より柔軟な書式設定やその他の追加機能が必要な場合は、UTC自体にゼロからのオフセットを適用し( ZoneOffset.UTC
定数 )、 OffsetDateTime
を取得します。
OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC );
コンソールにダンプ…
System.out.println( "now: " + now );
実行すると…
now: 2014-01-21T23:42:03.522Z
Java.timeクラスは JSR 31 によって定義されます。それらはJoda-Timeに触発されましたが、完全に再設計されています。
更新: Joda-Time プロジェクトは、現在 メンテナンスモード にあり、 Java.time クラスへの移行を推奨しています。
Joda-Time サードパーティのオープンソースの無料ライブラリを使用すると、わずか1行のコードで現在の日時を取得できます。
Joda-TimeはJava 8の新しいJava.time。*クラスに影響を与えましたが、アーキテクチャは異なります。 Joda-Timeは古いバージョンのJavaで使用できます。 Joda-TimeはJava 8で引き続き機能し、アクティブに維持され続けています(2014年時点)。ただし、Joda-TimeチームはJava.timeへの移行を推奨しています。
System.out.println( "UTC/GMT date-time in ISO 8601 format: " + new org.joda.time.DateTime( org.joda.time.DateTimeZone.UTC ) );
より詳細なコード例(Joda-Time 2.3)…
org.joda.time.DateTime now = new org.joda.time.DateTime(); // Default time zone.
org.joda.time.DateTime zulu = now.toDateTime( org.joda.time.DateTimeZone.UTC );
コンソールにダンプ…
System.out.println( "Local time in ISO 8601 format: " + now );
System.out.println( "Same moment in UTC (Zulu): " + zulu );
実行すると…
Local time in ISO 8601 format: 2014-01-21T15:34:29.933-08:00
Same moment in UTC (Zulu): 2014-01-21T23:34:29.933Z
タイムゾーンの作業を行うコードの例については、 my answer を参照してください。
JVMの現在のデフォルトのタイムゾーン(いつでも変更可能!)に暗黙的に依存するのではなく、常にタイムゾーンを指定することをお勧めします。そのような依存は、日時作業における混乱とバグの一般的な原因のようです。
now()
を呼び出すときは、割り当てるタイムゾーンを渡します。 DateTimeZone
クラスを使用します。
DateTimeZone zoneMontréal = DateTimeZone.forID( "America/Montreal" );
DateTime now = DateTime.now( zoneMontréal );
そのクラスは、 TCの定数 タイムゾーンを保持します。
DateTime now = DateTime.now( DateTimeZone.UTC );
JVMの現在のデフォルトのタイムゾーンを本当に使用する場合は、明示的な呼び出しを行って、コードが自己文書化されるようにします。
DateTimeZone zoneDefault = DateTimeZone.getDefault();
ISO 8601 形式についてお読みください。 Java.timeとJoda-Timeはどちらも、文字列の解析と生成の両方のデフォルトとして、その標準の賢明な形式を使用します。
† 実際、Java.util.Date doesにはタイムゾーンがあり、ソースコードのレイヤーの下に深く埋め込まれています。最も実用的な目的のために、そのタイムゾーンは無視されます。したがって、速記として、Java.util.Dateにはタイムゾーンがないと言います。さらに、その埋め込みタイムゾーンはnot DateのtoString
メソッドで使用されるものです。この方法では、JVMの現在のデフォルトのタイムゾーンが使用されます。この紛らわしいクラスを避け、Joda-TimeとJava.timeに固執するさらに多くの理由。
これは間違いなくUTC時間を返します:StringとDateオブジェクトとして!
static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static Date getUTCdatetimeAsDate() {
// note: doesn't check for null
return stringDateToDate(getUTCdatetimeAsString());
}
public static String getUTCdatetimeAsString() {
final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
final String utcTime = sdf.format(new Date());
return utcTime;
}
public static Date stringDateToDate(String StrDate) {
Date dateToReturn = null;
SimpleDateFormat dateFormat = new SimpleDateFormat(DATEFORMAT);
try {
dateToReturn = (Date)dateFormat.parse(StrDate);
}
catch (ParseException e) {
e.printStackTrace();
}
return dateToReturn;
}
Calendar c = Calendar.getInstance();
System.out.println("current: "+c.getTime());
TimeZone z = c.getTimeZone();
int offset = z.getRawOffset();
if(z.inDaylightTime(new Date())){
offset = offset + z.getDSTSavings();
}
int offsetHrs = offset / 1000 / 60 / 60;
int offsetMins = offset / 1000 / 60 % 60;
System.out.println("offset: " + offsetHrs);
System.out.println("offset: " + offsetMins);
c.add(Calendar.HOUR_OF_DAY, (-offsetHrs));
c.add(Calendar.MINUTE, (-offsetMins));
System.out.println("GMT Time: "+c.getTime());
実際には時間ではありませんが、表現は変更される可能性があります。
SimpleDateFormat f = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
f.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(f.format(new Date()));
地球のどの地点でも時間は同じですが、私たちの時間の認識は場所によって異なる場合があります。
カレンダーaGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone( "GMT"));その後、aGMTCalendarオブジェクトを使用して実行されるすべての操作はGMTタイムゾーンで実行され、夏時間や固定オフセットは適用されません。
違う!
Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
aGMTCalendar.getTime(); //or getTimeInMillis()
そして
Calendar aNotGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT-2"));aNotGMTCalendar.getTime();
同じ時間を返します。のアイデア
new Date(); //it's not GMT.
このコードは現在時刻のUTCを表示します。
import Java.text.ParseException;
import Java.text.SimpleDateFormat;
import Java.util.Date;
import Java.util.TimeZone;
public class Test
{
public static void main(final String[] args) throws ParseException
{
final SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
f.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(f.format(new Date()));
}
}
結果
2013-10-26 14:37:48 UTC
これは、AndroidでUTCミリ秒を取得するために機能します。
Calendar c = Calendar.getInstance();
int utcOffset = c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);
Long utcMilliseconds = c.getTimeInMillis() + utcOffset;
これは Jon Skeetの答え では正しくないようです。彼は言った:
Java.util.Date
は常にUTCです。現地時間だと思うのはどうしてですか。問題は、ローカルタイムゾーンを使用するCalendarのインスタンス、またはローカルタイムゾーンも使用するDate.toString()
を使用して表示していることです。
しかし、コード:
System.out.println(new Java.util.Date().getHours() + " hours");
gMT(UTC時間)ではなく、現地時間を表示します。no Calendar
とno SimpleDateFormat
を使用します。
だからこそ何かが間違っているようです。
レスポンスをまとめると、コードは次のようになります。
System.out.println(Calendar.getInstance(TimeZone.getTimeZone("GMT"))
.get(Calendar.HOUR_OF_DAY) + " Hours");
現地時間ではなくGMT時間を表示します - getTime.getHours()
は、理論的にはGMTに日付を格納しますが、現地時間帯の時間を返すDate()
オブジェクトを作成するため、欠落していることに注意してください。
UTC用に調整されたフィールドを持つDateオブジェクトが必要な場合は、 Joda Time を使用してこのように実行できます。
import org.joda.time.DateTimeZone;
import Java.util.Date;
...
Date local = new Date();
System.out.println("Local: " + local);
DateTimeZone zone = DateTimeZone.getDefault();
long utc = zone.convertLocalToUTC(local.getTime(), false);
System.out.println("UTC: " + new Date(utc));
あなたはこれを直接使うことができます
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(new Date())+"");
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(date));
あなたが使用することができます:
Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
その後、aGMTCalendarオブジェクトを使用して実行されるすべての操作はGMTタイムゾーンで実行され、夏時間や固定オフセットは適用されません。前のポスターは、Date()オブジェクトが常にGMTを返すというのは正しいと思います。dateオブジェクトを使ってローカルタイムゾーンに変換されるまで、それは行われません。
これはGMTタイムスタンプオブジェクトを取得するための他の提案です:
import Java.sql.Timestamp;
import Java.util.Calendar;
...
private static Timestamp getGMT() {
Calendar cal = Calendar.getInstance();
return new Timestamp(cal.getTimeInMillis()
-cal.get(Calendar.ZONE_OFFSET)
-cal.get(Calendar.DST_OFFSET));
}
GMT時刻を文字列形式で取得するもう1つの方法があります。
String DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss z" ;
final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String dateTimeString = sdf.format(new Date());
と:
Calendar cal = Calendar.getInstance();
それからcal
は現在の日付と時刻を持ちます。
タイムゾーンの現在の日付と時刻を取得することもできます。
Calendar cal2 = Calendar.getInstance(TimeZone.getTimeZone("GMT-2"));
他の詳細についてはcal.get(Calendar.DATE);
や他のCalendar constantに尋ねることができます。
日付とタイムスタンプはJavaでは推奨されていません。カレンダークラスではありません。
UTCで現在の日時を変換する:
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
DateTimeZone dateTimeZone = DateTimeZone.getDefault(); //Default Time Zone
DateTime currDateTime = new DateTime(); //Current DateTime
long utcTime = dateTimeZone.convertLocalToUTC(currDateTime .getMillis(), false);
String currTime = formatter.print(utcTime); //UTC time converted to string from long in format of formatter
currDateTime = formatter.parseDateTime(currTime); //Converted to DateTime in UTC
これを簡単にするために、Date
にUTC
を作成するには、 Calendar
を使用できます。
Calendar.getInstance(TimeZone.getTimeZone("UTC"));
これは "UTC" Calendar
を使用してTimeZone
の新しいインスタンスを構築します。
そのカレンダーからDate
オブジェクトが必要な場合は、getTime()
を使用することができます。
システム時間を特定のタイムゾーンおよび特定の形式で表示するためのサンプルコード。
import Java.text.SimpleDateFormat;
import Java.util.Calendar;
import Java.util.Date;
import Java.util.TimeZone;
public class TimZoneTest {
public static void main (String[] args){
//<GMT><+/-><hour>:<minutes>
// Any screw up in this format, timezone defaults to GMT QUIETLY. So test your format a few times.
System.out.println(my_time_in("GMT-5:00", "MM/dd/yyyy HH:mm:ss") );
System.out.println(my_time_in("GMT+5:30", "'at' HH:mm a z 'on' MM/dd/yyyy"));
System.out.println("---------------------------------------------");
// Alternate format
System.out.println(my_time_in("America/Los_Angeles", "'at' HH:mm a z 'on' MM/dd/yyyy") );
System.out.println(my_time_in("America/Buenos_Aires", "'at' HH:mm a z 'on' MM/dd/yyyy") );
}
public static String my_time_in(String target_time_zone, String format){
TimeZone tz = TimeZone.getTimeZone(target_time_zone);
Date date = Calendar.getInstance().getTime();
SimpleDateFormat date_format_gmt = new SimpleDateFormat(format);
date_format_gmt.setTimeZone(tz);
return date_format_gmt.format(date);
}
}
出力
10/08/2011 21:07:21
at 07:37 AM GMT+05:30 on 10/09/2011
at 19:07 PM PDT on 10/08/2011
at 23:07 PM ART on 10/08/2011
これが私のtoUTCの実装です。
public static Date toUTC(Date date){
long datems = date.getTime();
long timezoneoffset = TimeZone.getDefault().getOffset(datems);
datems -= timezoneoffset;
return new Date(datems);
}
おそらくそれを改善するためのいくつかの方法がありますが、それは私のために働きます。
public static void main(String args[]){
LocalDate date=LocalDate.now();
System.out.println("Current date = "+date);
}
これは私のために働きました、GMTのタイムスタンプを返します!
Date currDate;
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
long currTime = 0;
try {
currDate = dateFormatLocal.parse( dateFormatGmt.format(new Date()) );
currTime = currDate.getTime();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
日付の解析を避けてGMTでタイムスタンプだけが必要な場合は、次のようにします。
final Date gmt = new Timestamp(System.currentTimeMillis()
- Calendar.getInstance().getTimeZone()
.getOffset(System.currentTimeMillis()));
このクラスを使用して、オンラインNTPサーバーから正しいUTC時刻を取得します。
import Java.net.DatagramPacket;
import Java.net.DatagramSocket;
import Java.net.InetAddress;
class NTP_UTC_Time
{
private static final String TAG = "SntpClient";
private static final int RECEIVE_TIME_OFFSET = 32;
private static final int TRANSMIT_TIME_OFFSET = 40;
private static final int NTP_PACKET_SIZE = 48;
private static final int NTP_PORT = 123;
private static final int NTP_MODE_CLIENT = 3;
private static final int NTP_VERSION = 3;
// Number of seconds between Jan 1, 1900 and Jan 1, 1970
// 70 years plus 17 leap days
private static final long OFFSET_1900_TO_1970 = ((365L * 70L) + 17L) * 24L * 60L * 60L;
private long mNtpTime;
public boolean requestTime(String Host, int timeout) {
try {
DatagramSocket socket = new DatagramSocket();
socket.setSoTimeout(timeout);
InetAddress address = InetAddress.getByName(Host);
byte[] buffer = new byte[NTP_PACKET_SIZE];
DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, NTP_PORT);
buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3);
writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET);
socket.send(request);
// read the response
DatagramPacket response = new DatagramPacket(buffer, buffer.length);
socket.receive(response);
socket.close();
mNtpTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET);
} catch (Exception e) {
// if (Config.LOGD) Log.d(TAG, "request time failed: " + e);
return false;
}
return true;
}
public long getNtpTime() {
return mNtpTime;
}
/**
* Reads an unsigned 32 bit big endian number from the given offset in the buffer.
*/
private long read32(byte[] buffer, int offset) {
byte b0 = buffer[offset];
byte b1 = buffer[offset+1];
byte b2 = buffer[offset+2];
byte b3 = buffer[offset+3];
// convert signed bytes to unsigned values
int i0 = ((b0 & 0x80) == 0x80 ? (b0 & 0x7F) + 0x80 : b0);
int i1 = ((b1 & 0x80) == 0x80 ? (b1 & 0x7F) + 0x80 : b1);
int i2 = ((b2 & 0x80) == 0x80 ? (b2 & 0x7F) + 0x80 : b2);
int i3 = ((b3 & 0x80) == 0x80 ? (b3 & 0x7F) + 0x80 : b3);
return ((long)i0 << 24) + ((long)i1 << 16) + ((long)i2 << 8) + (long)i3;
}
/**
* Reads the NTP time stamp at the given offset in the buffer and returns
* it as a system time (milliseconds since January 1, 1970).
*/
private long readTimeStamp(byte[] buffer, int offset) {
long seconds = read32(buffer, offset);
long fraction = read32(buffer, offset + 4);
return ((seconds - OFFSET_1900_TO_1970) * 1000) + ((fraction * 1000L) / 0x100000000L);
}
/**
* Writes 0 as NTP starttime stamp in the buffer. --> Then NTP returns Time OFFSET since 1900
*/
private void writeTimeStamp(byte[] buffer, int offset) {
int ofs = offset++;
for (int i=ofs;i<(ofs+8);i++)
buffer[i] = (byte)(0);
}
}
そしてそれを使ってください。
long now = 0;
NTP_UTC_Time client = new NTP_UTC_Time();
if (client.requestTime("pool.ntp.org", 2000)) {
now = client.getNtpTime();
}
DateTimeStringとしてUTC Time "now"が必要な場合は、関数を使用します。
private String get_UTC_Datetime_from_timestamp(long timeStamp){
try{
Calendar cal = Calendar.getInstance();
TimeZone tz = cal.getTimeZone();
int tzt = tz.getOffset(System.currentTimeMillis());
timeStamp -= tzt;
// DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.getDefault());
DateFormat sdf = new SimpleDateFormat();
Date netDate = (new Date(timeStamp));
return sdf.format(netDate);
}
catch(Exception ex){
return "";
}
}
と一緒に使用します。
String UTC_DateTime = get_UTC_Datetime_from_timestamp(now);
簡単に言えば。カレンダオブジェクトにはタイムゾーンに関する情報が格納されていますが、cal.getTime()を実行するとタイムゾーン情報が失われます。だからタイムゾーン変換のために私はDateFormatクラスを使用することをお勧めします...
これは私の実装です:
public static String GetCurrentTimeStamp()
{
Calendar cal=Calendar.getInstance();
long offset = cal.getTimeZone().getOffset(System.currentTimeMillis());//if you want in UTC else remove it .
return new Java.sql.Timestamp(System.currentTimeMillis()+offset).toString();
}
public class CurrentUtcDate
{
public static void main(String[] args) {
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("UTC Time is: " + dateFormat.format(date));
}
}
出力:
UTC Time is: 22-01-2018 13:14:35
必要に応じて日付形式を変更できます。
もしあなたがjoda時間を使っていてミリ秒単位の現在時刻が欲しいならあなたのローカルオフセットなしであなたはこれを使うことができます:
long instant = DateTimeZone.UTC.getMillisKeepLocal(DateTimeZone.getDefault(), System.currentTimeMillis());
Java.timeパッケージを使用して、以下のコードをインクルードします。
ZonedDateTime now = ZonedDateTime.now( ZoneOffset.UTC );
または
LocalDateTime now2 = LocalDateTime.now( ZoneOffset.UTC );
アプリケーションのニーズに応じて.
UTCの現在の日付
Instant.now().toString().replaceAll("T.*", "");