2008-09-17 10 views
8

मैं एक डेटाबेस क्षेत्र है कि एक कच्चे दिनांक फ़ील्ड (चरित्र डेटा के रूप में जमा) शामिल हैं, इस तरह के रूपस्ट्रिंग से टाइमज़ोन ऑब्जेक्ट निकालने का सबसे अच्छा तरीका?

शुक्रवार, 26 सितंबर, 2008 8:30 PM पर पूर्वी डेलाइट समय

मैं पार्स कर सकते है इस के रूप में एक तिथि आसानी से SimpleDateFormat

DateFormat dbFormatter = new SimpleDateFormat("EEEE, MMMM dd, yyyy hh:mm aa zzzz"); 
Date scheduledDate = dbFormatter.parse(rawDate); 

साथ मैं क्या करना चाहते हैं क्या इस स्ट्रिंग से एक समयक्षेत्र वस्तु को निकालने के लिए है। JVM में डिफ़ॉल्ट टाइमज़ोन जो कि यह एप्लिकेशन जीएमटी में चलता है, इसलिए मैं ऊपर दिए गए Date से .getTimezoneOffset() का उपयोग नहीं कर सकता (क्योंकि यह डिफ़ॉल्ट टाइमज़ोन लौटाएगा)।

कच्चे स्ट्रिंग tokenizing और समय-क्षेत्र स्ट्रिंग के शुरू होने से स्थिति की खोज (के बाद से मैं जानता हूँ कि प्रारूप हमेशा EEEE, MMMM dd, yyyy hh:mm aa zzzz हो जाएगा) इसके अलावा वहाँ DateFormat/SimpleDateFormat/दिनांक/कैलेंडर API का उपयोग कर एक समयक्षेत्र वस्तु को निकालने के लिए एक तरीका है - जो स्ट्रिंग के रूप में एक ही टाइमज़ोन होगा, मैंने DateFormat.parse() के साथ अलग किया है?

एक बात है कि कीड़े के बारे में मुझे Date बनाम जावा एपीआई में Calendar कि Calendar सभी स्थानों में Date को बदलने के लिए माना जाता है ... लेकिन फिर उन्होंने फैसला किया, ओह हे चलो अभी भी DateFormat कक्षाओं में Date के इस्तेमाल करते हैं।

+0

क्या आपको इस मुद्दे के समाधान का समाधान मिला? – Chin2

+0

पिछले पैराग्राफ के संबंध में, 'तिथि' और 'कैलेंडर' कक्षाएं एक खूनी गड़बड़ी हैं: खराब-डिजाइन, भ्रमित और परेशानी। उनसे बचें। इसके बजाय [java.time] (http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) कक्षाओं का उपयोग करें। –

उत्तर

0

अच्छी तरह से आंशिक समाधान के रूप में आप टाइमज़ोन प्राप्त करने के लिए एक रेगेक्स मैच का उपयोग कर सकते हैं क्योंकि आपके पास हमेशा पहले एक ही टेक्स्ट होगा। पूर्वाह्न या अपराह्न।

मुझे जावा टाइमज़ोन के बारे में पर्याप्त जानकारी नहीं है ताकि आप इसका अंतिम भाग प्राप्त कर सकें।

2

मैंने पाया कि निम्नलिखित:

 DateFormat dbFormatter = new SimpleDateFormat("EEEE, MMMM dd, yyyy hh:mm aa zzzz"); 
     dbFormatter.setTimeZone(TimeZone.getTimeZone("America/Chicago")); 
     Date scheduledDate = dbFormatter.parse("Friday, September 26, 2008 8:30 PM Eastern Daylight Time"); 
     System.out.println(scheduledDate); 
     System.out.println(dbFormatter.format(scheduledDate)); 
     TimeZone tz = dbFormatter.getTimeZone(); 
     System.out.println(tz.getDisplayName()); 
     dbFormatter.setTimeZone(TimeZone.getTimeZone("America/Chicago")); 
     System.out.println(dbFormatter.format(scheduledDate)); 

निम्नलिखित का उत्पादन:

Fri Sep 26 20:30:00 CDT 2008 
Friday, September 26, 2008 08:30 PM Eastern Standard Time 
Eastern Standard Time 
Friday, September 26, 2008 08:30 PM Central Daylight Time 

मैं वास्तव में यह कुछ हद तक आश्चर्य की बात हो पाया। लेकिन, मुझे लगता है कि इससे पता चलता है कि आपके प्रश्न का उत्तर केवल पार्स किए जाने के बाद फॉर्मेट पर GetTimeZone को कॉल करना है।

संपादित करें: उपर्युक्त सूर्य के जेडीके 1.6 के साथ चलाया गया था।

+0

मैं इससे भी आश्चर्यचकित था और इससे पहले डेट इंस्टॉलेशन के कारण टाइमज़ोन स्लाइडिंग के साथ मुद्दों में भाग लिया था। – 18Rabbit

+0

बस उत्सुक - आपकी मशीन पर TimeZone.getDefault() का नतीजा क्या है? –

0

दिनांक और कैलेंडर के बीच मुख्य अंतर यह है कि तिथि केवल एक मूल्य वस्तु है जिसमें इसे संशोधित करने के लिए कोई तरीका नहीं है। इसलिए इसे कहीं दिनांक/समय की जानकारी संग्रहीत करने के लिए डिज़ाइन किया गया है। यदि आप कैलेंडर ऑब्जेक्ट का उपयोग करते हैं, तो आप इसे एक सतत इकाई पर सेट करने के बाद संशोधित कर सकते हैं जो दिनांक/समय की जानकारी के साथ कुछ व्यावसायिक तर्क करता है। यह बहुत खतरनाक है, क्योंकि इस परिवर्तन को पहचानने के लिए इकाई का कोई तरीका नहीं है। कैलेंडर क्लास दिनांक/समय पर संचालन के लिए डिज़ाइन किया गया है, जैसे दिन या कुछ ऐसा जोड़ना।

अपने उदाहरण के साथ चारों ओर खेलने मैं निम्नलिखित मिल:

import java.text.DateFormat; 
import java.text.ParseException; 
import java.text.SimpleDateFormat; 

public class TimeZoneExtracter { 

    public static final void main(String[] args) throws ParseException { 
     DateFormat dbFormatter = new SimpleDateFormat("EEEE, MMMM dd, yyyy hh:mm aa zzzz"); 
     System.out.println(dbFormatter.getTimeZone()); 
     dbFormatter.parse("Fr, September 26, 2008 8:30 PM Eastern Daylight Time"); 
     System.out.println(dbFormatter.getTimeZone()); 
    } 

} 

आउटपुट:

sun.util.calendar.ZoneInfo [id = "यूरोप/बर्लिन" ... सूरज। util.calendar.ZoneInfo [id = "अफ्रीका/Addis_Ababa" ...

क्या यह परिणाम आप चाहते थे?

1

@Ed थॉमस:

मैं बहुत अपने उदाहरण की तरह कुछ की कोशिश की है और मैं बहुत अलग परिणाम प्राप्त:

String testString = "Friday, September 26, 2008 8:30 PM Pacific Standard Time"; 
DateFormat df = new SimpleDateFormat("EEEE, MMMM dd, yyyy hh:mm aa zzzz"); 

System.out.println("The default TimeZone is: " + TimeZone.getDefault().getDisplayName()); 

System.out.println("DateFormat timezone before parse: " + df.getTimeZone().getDisplayName()); 

Date date = df.parse(testString); 

System.out.println("Parsed [" + testString + "] to Date: " + date); 

System.out.println("DateFormat timezone after parse: " + df.getTimeZone().getDisplayName()); 

आउटपुट:

डिफ़ॉल्ट समय क्षेत्र है: पूर्वी मानक समय

पार्स से पहले डेटफॉर्मेट टाइमज़ोन: पूर्वी मानक समय

पार्स किया गया [शुक्रवार, 26 सितंबर, 2008 8:30 PM पर प्रशांत मानक समय] तिथि करने के लिए: शनि सितं, 27 00:30:00 EDT 2008

DateFormat समय क्षेत्र पार्स के बाद: पूर्वी मानक समय

ऐसा लगता है कि DateFormat.getTimeZone()parse() से पहले और उसके बाद एक ही टाइमज़ोन देता है ... भले ही मैं parse() पर कॉल करने से पहले एक स्पष्ट setTimeZone() में फेंक दूं।

DateFormat और SimpleDateFormat के लिए स्रोत को देखते हुए, लगता है getTimeZone() सिर्फ अंतर्निहित कैलेंडर ... जो सामान्य स्थान/समय क्षेत्र का कैलेंडर के लिए डिफ़ॉल्ट जब तक आप का उपयोग करने के लिए एक निश्चित एक निर्दिष्ट करेगा की समयक्षेत्र रिटर्न की तरह।

+0

आप किस जेवीएम का उपयोग कर रहे हैं? –

+0

जावा संस्करण "1.4.2_14" जावा (टीएम) 2 रनटाइम पर्यावरण, मानक संस्करण (1.4.2_14-बी05 बनाएं) जावा हॉटस्पॉट (टीएम) क्लाइंट वीएम (1.4.2_14-बी05, मिश्रित मोड बनाएं) –

0

एड यह सही है। आप समय के बाद डेटफॉर्म ऑब्जेक्ट पर समय ज़ोन चाहते हैं।

String rawDate = "Friday, September 26, 2008 8:30 PM Eastern Daylight Time"; 
DateFormat dbFormatter = new SimpleDateFormat("EEEE, MMMM dd, yyyy hh:mm aa zzzz"); 
Date scheduledDate = dbFormatter.parse(rawDate); 

System.out.println(rawDate); 
System.out.println(scheduledDate); 
System.out.println(dbFormatter.getTimeZone().getDisplayName()); 

Friday, September 26, 2008 8:30 PM Eastern Daylight Time 
Fri Sep 26 20:30:00 CDT 2008 
Eastern Standard Time 
+2

आप चाहें स्ट्रिंग - dbFormatter.getTimeZone() में "पूर्वी डेलाइट टाइम" के अलावा किसी अन्य चीज़ के साथ परीक्षण करने के लिए बस डिफ़ॉल्ट (आपका) टाइमज़ोन लौट रहा है। –

1

मैं Joda समय दिनांक और समय एपीआई देखने की अनुशंसा पैदा करता है। मुझे हाल ही में इसमें एक आस्तिक में परिवर्तित कर दिया गया है क्योंकि यह जावा में तिथियों और समय के लिए अंतर्निहित समर्थन से अत्यधिक बेहतर है। विशेष रूप से, आपको डेटटाइमज़ोन कक्षा की जांच करनी चाहिए। उम्मीद है की यह मदद करेगा।

http://joda-time.sourceforge.net/

http://joda-time.sourceforge.net/api-release/index.html

0

tl; डॉ

ZonedDateTime.parse( 
    "Friday, September 26, 2008 8:30 PM Eastern Daylight Time" , 
    DateTimeFormatter.ofPattern("EEEE, MMMM d, uuuu h:m a zzzz") 
).getZone() 

java.time

आधुनिक तरीका java.time वर्गों के साथ है। प्रश्न और अन्य उत्तर परेशानी पुरानी विरासत डेट-टाइम कक्षाओं या जोडा-टाइम प्रोजेक्ट का उपयोग करते हैं, जिनमें से दोनों अब जावा.टाइम कक्षाओं द्वारा सप्लाई किए जाते हैं।

अपने डेटा से मेल खाने के लिए एक स्वरूपण पैटर्न के साथ DateTimeFormatter ऑब्जेक्ट को परिभाषित करें।

DateTimeFormatter f = DateTimeFormatter.ofPattern("EEEE, MMMM d, uuuu h:m a zzzz"); 

नाम के- दिन और महीने के नाम के मानव भाषा, साथ ही अन्य स्वरूपण मुद्दों के लिए सांस्कृतिक मानकों निर्दिष्ट करने के लिए एक Locale असाइन करें।

f = f.withLocale(Locale.US); 

आखिरकार, ZonedDateTime ऑब्जेक्ट प्राप्त करने के लिए पार्सिंग करें।

String input = "Friday, September 26, 2008 8:30 PM Eastern Daylight Time" ; 
ZonedDateTime zdt = ZonedDateTime.parse(input , f); 

zdt.toString(): 2008-09-26T20: 30-04: 00 [America/New_York]

आप ZonedDateTime, के रूप में प्रतिनिधित्व से समय क्षेत्र के लिए पूछ सकते हैं ZoneId ऑब्जेक्ट। यदि आप समय क्षेत्र के बारे में अधिक जानकारी चाहते हैं तो आप ZoneId से पूछताछ कर सकते हैं।

ZoneId z = zdt.getZone(); 

See for yourself in IdeOne.com

आईएसओ 8601

बचें भयानक प्रारूप इस तरह का में तारीख समय डेटा का आदान प्रदान। अंग्रेजी न मानें, अपने आउटपुट को दिन-सारिणी जैसी चीज़ों के साथ एक्सेस न करें, और Eastern Daylight Time जैसे छद्म-समय-क्षेत्रों का उपयोग न करें।

समय क्षेत्रों के लिए: continent/region के प्रारूप में एक proper time zone name निर्दिष्ट करें, America/Montreal जैसे, Africa/Casablanca, या Pacific/Auckland। कभी भी 0-या IST जैसे 3-4 अक्षर संक्षेप का उपयोग न करें क्योंकि वे सही समय क्षेत्र नहीं हैं, मानकीकृत नहीं हैं, और यहां तक ​​कि अद्वितीय (!) भी नहीं हैं।

टेक्स्ट के लिए दिनांक-समय मानों को क्रमबद्ध करने के लिए, केवल ISO 8601 स्वरूपों का उपयोग करें। Java.time कक्षाएं डिफ़ॉल्ट रूप से इन स्वरूपों का उपयोग करती हैं जब स्ट्रिंग को उनके मूल्य का प्रतिनिधित्व करने के लिए पार्सिंग/जनरेट करते हैं।


java.time

बारे java.time ढांचे जावा 8 और बाद में बनाया गया है। ये कक्षाएं परेशान पुराने legacyjava.util.Date, Calendar, & SimpleDateFormat जैसी समय-समय पर कक्षाएं प्रदान करती हैं।

Joda-Time प्रोजेक्ट, अब maintenance mode में, जावा.टाइम पर माइग्रेशन की सलाह देता है।

और जानने के लिए, Oracle Tutorial देखें। और कई उदाहरणों और स्पष्टीकरणों के लिए स्टैक ओवरफ़्लो खोजें। विशिष्टता JSR 310 है।

जावा.टाइम कक्षाएं कहां प्राप्त करें?

  • Java SE 8 और SE 9 और बाद में
    • में निर्मित।
    • एक बंडल कार्यान्वयन के साथ मानक जावा एपीआई का हिस्सा।
    • जावा 9 कुछ मामूली विशेषताओं और सुधारों को जोड़ता है।
  • Java SE 6 और SE 7
    • java.time कार्यक्षमता की ज्यादातर ThreeTen-Backport में जावा 6 & से 7 वापस भेजा गया है।
  • Android
    • ThreeTenABP परियोजना adapts ThreeTen-backport विशेष रूप से (जैसा कि ऊपर उल्लेख) Android के लिए।
    • How to use… देखें।

ThreeTen-Extra परियोजना अतिरिक्त कक्षाओं के साथ java.time फैली हुई है। यह परियोजना java.time के संभावित भविष्य के जोड़ों के लिए एक सिद्ध भूमि है। आपको यहां कुछ उपयोगी कक्षाएं मिल सकती हैं जैसे Interval, YearWeek, YearQuarter, और more

संबंधित मुद्दे

 संबंधित मुद्दे