Java Zaman Damgası - 23/09/2007 tarihli bir Zaman Damgasını nasıl oluşturabilirim?


Yanıtlar:


156

By Timestamp, ne demek farz java.sql.Timestamp. Bu sınıfın bir longargümanı kabul eden bir kurucuya sahip olduğunu fark edeceksiniz . Bunu DateFormatsınıfı kullanarak ayrıştırabilirsiniz :

DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Date date = dateFormat.parse("23/09/2007");
long time = date.getTime();
new Timestamp(time);

1
Normal ISO tarih biçimi yyyy-MM-gg'dir, aksi takdirde harika!
vidstige

1
yeni Zaman Damgası (zaman); Böyle uzun bir değer almayan hiçbir kurucunun hata vermesi :(
Bhanu Sharma

1
@Bhanu Dokümanlar bunun uzun bir değer aldığını ve düzgün çalıştığını gösteriyor: docs.oracle.com/javase/7/docs/api/java/sql/…
Hazok

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 Eğitimine bakın .
Basil Bourque

121

Peki buna ne dersin?

java.sql.Timestamp timestamp = java.sql.Timestamp.valueOf("2007-09-23 10:10:10.0");

1
Zaman damgası zaman damgası = Timestamp.valueOf ("2007-09-23 10: 10: 10.0"); jDK 7'de Timestamp türü için valueOf yönteminin tanımsız olduğunu gösteriyor
Ashish Ratan

yeni Zaman Damgası (zaman); bunun gibi bir dize değeri alan hiçbir kurucunun hata vermesi :(
Bhanu Sharma

@Bhanu Oluşturucu unix süresini milisaniye cinsinden alır. Bir dizeden zaman damgası almak istiyorsanız statik yöntem valueOf kullanın.
Hazok

4
Bu soru için en iyi cevap gibi görünüyor.
Hazok

1
En iyi yanıt, kullanımdan kaldırılmış olan Date'e sahiptir, onu kullanmak kötü bir uygulamadır. Bu cevaplar daha iyi. Teşekkürler
Alberici

18

Zaman damgası ne demek? Unix döneminden beri geçen milisaniyeleri kastediyorsanız:

GregorianCalendar cal = new GregorianCalendar(2007, 9 - 1, 23);
long millis = cal.getTimeInMillis();

Gerçek bir java.sql.Timestamp nesnesi istiyorsanız:

Timestamp ts = new Timestamp(millis);

2
YANLIŞ ve derlenmeyecek! Derleme hatası: 09 sekizlik bir sayıdır, ancak 9 sekizli için aralık dışında. Mantık hatası: ay 0 temelli, 23 EKİM 2007
user85421

Derlenmezse mantık hatası alamıyorum. :) Cidden, iyi yakalamalar Carlos. Daha önce yakaladığım ama yine de yanlış yapıştırdığım sekizlik. :(
Matthew Flaschen

Aslında Timestamp kurucusu, Timestamp.valueOf () yöntemini kullanmak yerine kullanım dışı
bırakıldı

@ShivaKomuravelly tüm damgası yapıcı kaldırıldığını ve en az değil, milisaniye sürece argüman kullanımdan kaldırılmıştır olarak tarih alan kurucuya aldığı
adı yok

Ve bunun için bir sabit var (ay = 9 yerine):Calendar.SEPTEMBER
Guillaume Husta

12

tl; dr

java.sql.Timestamp.from (
    LocalDate.of ( 2007 , 9 , 23 )
             .atStartOfDay( ZoneId.of ( "America/Montreal" ) )
             .toInstant()
)

java.time

Java 8 ve sonraki sürümlerde yerleşik olan java.time çerçevesini kullanarak kodu göstererek bu sayfayı güncelleyelim .

Bu yeni sınıflar, JSR 310 tarafından tanımlanan Joda-Time'dan esinlenmiştir ve ThreeTen-Extra projesi ile genişletilmiştir . Java'nın eski sürümleriyle birlikte gelen, kötü şöhretli zahmetli eski tarih-saat sınıflarının yerini alıyorlar.

Java.time'da, InstantUTC'de zaman çizelgesindeki bir andır. A ZonedDateTime, bir saat dilimine ( ZoneId) ayarlanmış bir Anlıktır .

Saat dilimi burada çok önemlidir. Bir tarih, September 23, 2007bir saat dilimi uygulanmadan zaman çizelgesindeki bir ana çevrilemez. Paris'te yeni bir günün hala "dün" olduğu Montréal'den daha erken doğduğunu düşünün.

Ayrıca, java.sql.Timestamp hem tarihi hem de günün saatini temsil eder. Bu yüzden, tarihe uymak için günün saatini enjekte etmeliyiz. Günün ilk anını günün saati olarak istediğinizi varsayıyoruz. 00:00:00.0Yaz Saati Uygulaması ve muhtemelen diğer anormallikler nedeniyle bunun her zaman geçerli olmadığını unutmayın .

Eski java.util.Date sınıfından ve Joda-Time'dan farklı olarak java.time türlerinin milisaniye yerine nanosaniye çözünürlüğüne sahip olduğuna dikkat edin. Bu, java.sql.Timestamp'ın çözünürlüğü ile eşleşir.

Java.sql.Timestamp öğesinin, toStringyöntemi aracılığıyla bir dize gösterimi oluştururken JVM'nizin geçerli varsayılan saat dilimini tarih-saat değerine örtük olarak uygulama gibi kötü bir alışkanlığı olduğunu unutmayın . Burada America/Los_Angelessaat dilimimin uygulandığını görüyorsunuz . Buna karşılık, standart ISO 8601 formatlarını kullanan java.time sınıfları daha mantıklıdır .

LocalDate d = LocalDate.of ( 2007 , 9 , 23 ) ;
ZoneId z = ZoneId.of ( "America/Montreal" ) ;
ZonedDateTime zdt = d.atStartOfDay( z ) ;
Instant instant = zdt.toInstant() ;
java.sql.Timestamp ts = java.sql.Timestamp.from ( instant ) ;

Konsola boşaltın.

System.out.println ( "d: " + d + " = zdt: " + zdt + " = instant: " + instant + " = ts: " + ts );

Çalıştırıldığında.

d: 2007-09-23 = zdt: 2007-09-23T00: 00-04: 00 [Amerika / Montreal] = anlık: 2007-09-23T04: 00: 00Z = ts: 2007-09-22 21:00: 00.0

Bu arada, JDBC 4.2'den itibaren, java.time türlerini doğrudan kullanabilirsiniz. Gerek yok java.sql.Timestamp.

  • PreparedStatement.setObject
  • ResultSet.getObject

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.

Şu anda bakım modunda olan Joda-Time projesi, java.time sınıflarına geçişi önerir .

Daha fazla bilgi edinmek için Oracle Eğitimi'ne bakın . Ve birçok örnek ve açıklama için Stack Overflow'da arama yapın. Spesifikasyon JSR 310'dur .

Sen değiştirebilir java.time sizin veritabanı ile doğrudan nesneleri. JDBC 4.2 veya üstü ile uyumlu bir JDBC sürücüsü kullanın . Dizelere gerek yok, derslere gerek yok .java.sql.*

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

ThreeTen-Ekstra proje ek sınıfları ile java.time uzanır. Bu proje, java.time uygulamasına gelecekteki olası eklemeler için kanıtlayıcı bir zemindir. Burada bazı yararlı sınıfları gibi bulabilir Interval, YearWeek, YearQuarter, ve daha .


3
Cevabınızı doğru olarak işaretlemek için nasıl OP veya modlar edinebileceğimi merak ediyorum. Kabul edilen cevap çok eski.
sttaq

Yazım hatası dışında çok güzel. asStartOfDay () atStartOfDay () olmalıdır.
Tullochgorum

@Tullochgorum Düzeltildi. Teşekkürler. Bilginize, Stack Overflow'da, bu kadar istekliyseniz, bu tür düzenlemeleri kendiniz yapabilirsiniz.
Basil Bourque

5

Ayrıca şunları da yapabilirsiniz:

// untested
Calendar cal = GregorianCalendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 23);// I might have the wrong Calendar constant...
cal.set(Calendar.MONTH, 8);// -1 as month is zero-based
cal.set(Calendar.YEAR, 2009);
Timestamp tstamp = new Timestamp(cal.getTimeInMillis());

2
YANLIŞ: sonucun System.out.println dosyasını deneyin! Şöyle bir şey elde edeceksiniz: "2009-10-23 15: 26: 56.171" Ay 0 temelli, bu nedenle 9 Ekim!
user85421

Bu sabitlerden birinin sıfır tabanlı olduğunu biliyordum, teşekkürler. Gönderi güncellendi.
Alex

1
Oh, ve 'denenmemiş' yazdım :)
Alex

4

API'ye göre yıl, ay vb. Kabul eden kurucu kullanımdan kaldırılmıştır. Bunun yerine, uzun kabul eden Oluşturucu kullanmalısınız. İstediğiniz tarihi oluşturmak için bir Takvim uygulaması kullanabilir ve örneğin getTimeInMillis yöntemiyle zaman temsiline uzun olarak erişebilirsiniz .


1

Tamlık adına , Joda-Time sürüm 2.5 ve DateTimesınıfıyla da bir çözüm :

new Timestamp(new DateTime(2007, 9, 23, 0, 0, DateTimeZone.forID( "America/Montreal" )).getMillis())

1
Güzel yanıt, ancak çok önemli bir parçayı kaçırdınız : saat dilimi . Bir saat dilimini atlarsanız, DateTimenesneye JVM'nin geçerli varsayılan saat dilimi uygulanır . Bu, sonuçlarınızın çeşitli bilgisayarlara veya ana işletim sistemi yapılandırmasına veya JVM ayarlarına göre değişeceği anlamına gelir . Tahmin edilebilir sonuçlar için o kurucuya bir saat dilimi DateTimegeçirin. Niyetinize uygun saat dilimi adını seçin . Örneğin, DateTimeZone.forID( "America/Montreal" )veya DateTimeZone.UTC.
Basil Bourque

Bu kod daha kısa olabilir. Java.util.Date için dönüştürmek gerek yok olsun ve milisaniye-since- geçmek devrin . DateTimeNesneye, çağından beri geçen milisaniyesini sorun . Değiştir .toDate().getTime()ile .getMillis().
Basil Bourque

@BasilBourque Koşullara bağlı olarak, tahmin edilebilir sonuçlar elde etmek için saat dilimini dışarıda bırakmak isteyebilirsiniz. "Geçerli saat diliminize göre", tamamen makul ve öngörülebilir bir sonuç olabilir. Neden bir saat dilimini kodlayasınız ya da kullanıcılardan bilgisayarlarında zaten bir saat dilimi ayarlanmışken manuel olarak bir saat dilimi ayarlamalarını isteyesiniz? Bilgisayarımdaki bir uygulama Amerika / Montreal saat dilimine göre ayarlanmış tarihler vermeye başlarsa kesinlikle şaşırırım.
dan carter

@dancarter İsteğe bağlı saat diliminin atlanması kafa karışıklığına neden olur. Bu eksiklik, (a) programcı örtük varsayılana güvenmeyi amaçladı mı veya (b) programcı saat dilimi sorunlarını dikkate almadı mı (çok yaygın olduğu gibi) belirsizliğini ortaya çıkarır. JVM'nin geçerli varsayılan saat dilimini gerçekten kullanmak istiyorsanız , sonucu isteğe bağlı bağımsız değişken olarak çağırıp ileterek bunu açıkça söyleyinDateTimeZone.getDefault() . (Bu arada, Locale.getDefault()isteğe bağlı argümanların belirsizliği üzerine aynı mesele.)
Basil Bourque

-1

Daha genel bir cevap içe aktarmak olacaktır java.util.Date, o zaman timestampgeçerli tarihe eşit bir değer belirlemeniz gerektiğinde, basitçe olarak ayarlayın new Date().


çünkü ** Tarih ("dize"); ** kullanımdan kaldırıldı
Ashish Ratan
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.