Kāds ir labākais veids, kā pārvērst String
formātā '2. janvāris 2010' uz Date
Java?
Galu galā es gribu sadalīt mēnesi, dienu un gadu kā veselos skaitļus, lai es varētu izmantot
Date date = new Date();
date.setMonth()..
date.setYear()..
date.setDay()..
date.setlong currentTime = date.getTime();
pārvērst datumu laikā.
Tas ir sarežģītais veids, un šīs java.util.Date
iestatīšanas metodes ir atceltas kopš Java 1.1 (1997). Vienkārši formatējiet datumu, izmantojot SimpleDateFormat
, izmantojot formāta paraugu, kas atbilst ievades virknei.
Jūsu konkrētajā gadījumā "2010. gada 2. janvāris" kā ievades virkne:
MMMM
šablonu.d
rakstu.yyyy
modeli.String string = "January 2, 2010";
DateFormat format = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH);
Date date = format.parse(string);
System.out.println(date); // Sat Jan 02 00:00:00 GMT 2010
Ievērojiet, cik svarīgs ir skaidri norādītais Locale
arguments. Ja to izlaidīsiet, tiks izmantota noklusējuma vietne, kas ne vienmēr ir angļu valoda, kas izmantota ievades virknes mēneša nosaukumā. Ja locale nesakrīt ar ievades virkni, tad jūs mulsinoši saņemsiet java.text.ParseException
, pat ja formāta modelis šķiet derīgs.
Lūk, izraksts no javadoc, kurā uzskaitīti visi pieejamie formāta paraugi:
Letter Date or Time Component Presentation Examples
------ ---------------------- ------------------ -------------------------------------
G Era designator Text AD
y Year Year 1996; 96
Y Week year Year 2009; 09
M/L Month in year Month July; Jul; 07
w Week in year Number 27
W Week in month Number 2
D Day in year Number 189
d Day in month Number 10
F Day of week in month Number 2
E Day in week Text Tuesday; Tue
u Day number of week Number 1
a Am/pm marker Text PM
H Hour in day (0-23) Number 0
k Hour in day (1-24) Number 24
K Hour in am/pm (0-11) Number 0
h Hour in am/pm (1-12) Number 12
m Minute in hour Number 30
s Second in minute Number 55
S Millisecond Number 978
z Time zone General time zone Pacific Standard Time; PST; GMT-08:00
Z Time zone RFC 822 time zone -0800
X Time zone ISO 8601 time zone -08; -0800; -08:00
Ņemiet vērā, ka šabloni ir atkarīgi no mazajiem un lielajiem burtiem un ka četru vai vairāk rakstzīmju teksta šabloni ir pilnā formā; citādi tiek izmantota īsā vai saīsinātā forma, ja tāda ir pieejama. Tāpēc, piemēram, MMMMM
vai vairāk nav nepieciešams.
Šeit ir daži derīgu SimpleDateFormat
paraugu piemēri, lai analizētu doto virkni līdz datumam:
Input string Pattern
------------------------------------ ----------------------------
2001.07.04 AD at 12:08:56 PDT yyyy.MM.dd G 'at' HH:mm:ss z
Wed, Jul 4, '01 EEE, MMM d, ''yy
12:08 PM h:mm a
12 o'clock PM, Pacific Daylight Time hh 'o''clock' a, zzzz
0:08 PM, PDT K:mm a, z
02001.July.04 AD 12:08 PM yyyyy.MMMM.dd GGG hh:mm aaa
Wed, 4 Jul 2001 12:08:56 -0700 EEE, d MMM yyyy HH:mm:ss Z
010704120856-0700 yyMMddHHmmssZ
2001-07-04T12:08:56.235-0700 yyyy-MM-dd'T'HH:mm:ss.SSSZ
2001-07-04T12:08:56.235-07:00 yyyy-MM-dd'T'HH:mm:ss.SSSXXX
2001-W27-3 YYYY-'W'ww-u
Svarīgi atzīmēt, ka SimpleDateFormat
nav neierobežo pavedienu drošību. Citiem vārdiem sakot, nekad nevajadzētu deklarēt un piešķirt to kā statisku vai gadījuma mainīgo un pēc tam atkārtoti izmantot to dažādās metodēs/ritmos. Tas vienmēr jāveido pilnīgi jauns metodes lokālajā darbības jomā.
Ja izmantojat Java 8 vai jaunāku versiju, izmantojiet DateTimeFormatter
(arī šeit, noklikšķiniet uz saites, lai apskatītu visus iepriekš definētos formatētājus un pieejamos formātu paraugus; pamācība ir pieejama šeit). Šī jaunā API ir iedvesmojusies no JodaTime.
String string = "January 2, 2010";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM d, yyyy", Locale.ENGLISH);
LocalDate date = LocalDate.parse(string, formatter);
System.out.println(date); // 2010-01-02
Piezīme: ja jūsu formāta paraugs satur arī laika daļu, tad izmantojiet LocalDateTime#parse(text, formatter)
, nevis LocalDate#parse(text, formatter)
. Un, ja jūsu formāta paraugs satur arī laika zonu, tad tā vietā izmantojiet ZonedDateTime#parse(text, formatter)
.
Lūk, izraksts no javadoc, kurā uzskaitīti visi pieejamie formāta paraugi:
Symbol Meaning Presentation Examples
------ -------------------------- ------------ ----------------------------------------------
G era text AD; Anno Domini; A
u year year 2004; 04
y year-of-era year 2004; 04
D day-of-year number 189
M/L month-of-year number/text 7; 07; Jul; July; J
d day-of-month number 10
Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter
Y week-based-year year 1996; 96
w week-of-week-based-year number 27
W week-of-month number 4
E day-of-week text Tue; Tuesday; T
e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T
F week-of-month number 3
a am-pm-of-day text PM
h clock-hour-of-am-pm (1-12) number 12
K hour-of-am-pm (0-11) number 0
k clock-hour-of-am-pm (1-24) number 0
H hour-of-day (0-23) number 0
m minute-of-hour number 30
s second-of-minute number 55
S fraction-of-second fraction 978
A milli-of-day number 1234
n nano-of-second number 987654321
N nano-of-day number 1234000000
V time-zone ID zone-id America/Los_Angeles; Z; -08:30
z time-zone name zone-name Pacific Standard Time; PST
O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00;
X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15;
x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15;
Z zone-offset offset-Z +0000; -0800; -08:00;
Ņemiet vērā, ka tam ir vairāki iepriekš definēti formatētāji populārākiem paraugiem. Tā vietā, piemēram, DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH);
, jūs varētu izmantot DateTimeFormatter.RFC_1123_DATE_TIME
. Tas ir iespējams, jo, atšķirībā no SimpleDateFormat
, tie ir droši pret vītnēm. Tādējādi, ja nepieciešams, jūs varētu definēt arī savu.
Konkrētam ievades virknes formātam nav nepieciešams izmantot skaidru DateTimeFormatter
: standarta ISO 8601 datumu, piemēram, 2016-09-26T17:44:57Z, var analizēt tieši ar LocalDateTime#parse(text)
, jo tas jau izmanto ISO_LOCAL_DATE_TIME
formatētāju. Līdzīgi LocalDate#parse(text)
analizē ISO datumu bez laika komponenta (sk. ISO_LOCAL_DATE
), un ZonedDateTime#parse(text)
analizē ISO datumu ar nobīdi un laika zonu (sk. ISO_ZONED_DATE_TIME
).
Ak jā, atkal diskusija par Java datumu. Lai veiktu manipulācijas ar datumu, mēs izmantojam Date, Calendar, GregorianCalendar un SimpleDateFormat. Piemēram, kā ievadi izmantojiet savu janvāra datumu:
Calendar mydate = new GregorianCalendar();
String mystring = "January 2, 2010";
Date thedate = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse(mystring);
mydate.setTime(thedate);
//breakdown
System.out.println("mydate -> "+mydate);
System.out.println("year -> "+mydate.get(Calendar.YEAR));
System.out.println("month -> "+mydate.get(Calendar.MONTH));
System.out.println("dom -> "+mydate.get(Calendar.DAY_OF_MONTH));
System.out.println("dow -> "+mydate.get(Calendar.DAY_OF_WEEK));
System.out.println("hour -> "+mydate.get(Calendar.HOUR));
System.out.println("minute -> "+mydate.get(Calendar.MINUTE));
System.out.println("second -> "+mydate.get(Calendar.SECOND));
System.out.println("milli -> "+mydate.get(Calendar.MILLISECOND));
System.out.println("ampm -> "+mydate.get(Calendar.AM_PM));
System.out.println("hod -> "+mydate.get(Calendar.HOUR_OF_DAY));
Pēc tam ar to var manipulēt, izmantojot, piemēram:
Calendar now = Calendar.getInstance();
mydate.set(Calendar.YEAR,2009);
mydate.set(Calendar.MONTH,Calendar.FEBRUARY);
mydate.set(Calendar.DAY_OF_MONTH,25);
mydate.set(Calendar.HOUR_OF_DAY,now.get(Calendar.HOUR_OF_DAY));
mydate.set(Calendar.MINUTE,now.get(Calendar.MINUTE));
mydate.set(Calendar.SECOND,now.get(Calendar.SECOND));
// or with one statement
//mydate.set(2009, Calendar.FEBRUARY, 25, now.get(Calendar.HOUR_OF_DAY), now.get(Calendar.MINUTE), now.get(Calendar.SECOND));
System.out.println("mydate -> "+mydate);
System.out.println("year -> "+mydate.get(Calendar.YEAR));
System.out.println("month -> "+mydate.get(Calendar.MONTH));
System.out.println("dom -> "+mydate.get(Calendar.DAY_OF_MONTH));
System.out.println("dow -> "+mydate.get(Calendar.DAY_OF_WEEK));
System.out.println("hour -> "+mydate.get(Calendar.HOUR));
System.out.println("minute -> "+mydate.get(Calendar.MINUTE));
System.out.println("second -> "+mydate.get(Calendar.SECOND));
System.out.println("milli -> "+mydate.get(Calendar.MILLISECOND));
System.out.println("ampm -> "+mydate.get(Calendar.AM_PM));
System.out.println("hod -> "+mydate.get(Calendar.HOUR_OF_DAY));
Strādājot ar SimpleDateFormat klasi, ir svarīgi atcerēties, ka Date nav thread-safe un vienu Date objektu nevar koplietot ar vairākiem pavedieniem.
Turklāt ir liela atšķirība starp "m" un "M", kur mazo burtu lieto minūtēm, bet lielo burtu lieto mēnesim. Tas pats ir ar "d" un "D". Tas var radīt smalkas kļūdas, kuras bieži vien netiek pamanītas. Sīkāku informāciju skatiet Javadoc vai Guide to Convert String to Date in Java.