PHP

2009-07-19 3 views
5

के साथ उन्नत दिनांक-सत्यापन मुझे अपने वर्तमान प्रोजेक्ट के साथ कई तिथियां मान्य करनी होंगी। दुर्भाग्यवश, ये तिथियां जंगली रूप से भिन्न हो सकती हैं। उदाहरणों में शामिल हैं:PHP

  1. 1983-07-10 (1970 के बाद)
  2. 1492-10-11 (1970 से पहले, यूनिक्स टाइमस्टैम्प के वर्ष - इस strtotime() कुछ सिस्टम पर समाप्त)
  3. 200 ईसा पूर्व (वास्तव में पुराना ...)

तिथियां 99 99 बीसी से अधिक नहीं होंगी, न ही वे भविष्य (आज 'से परे) होंगे। यह सत्यापित करने का सबसे अच्छा तरीका क्या होगा कि सबमिट किए गए मान वास्तव में तिथियां हैं, और उस पर उचित तिथियां हैं?

अपडेट ...

सभी तिथियों अपने वैश्विक सूची के भीतर sortable होना चाहिए। उपरोक्त अर्थ 1 और 3 एक-दूसरे के साथ तुलनीय होना चाहिए, और एएससी या डीईएससी को सॉर्ट किया जाना चाहिए।

मैं अतीत में किए गए कैलेंडर-परिवर्तनों और इन परिवर्तनों के आसपास भ्रम के बारे में पूरी तरह से अवगत हूं। मेरा प्रोजेक्ट मानता है कि उपयोगकर्ता ने हमारे आधुनिक कैलेंडर प्रणाली के अनुसार तारीख को खोजने के लिए पहले ही उचित अंशांकन किया है। मैं उनके लिए यह अंशांकन नहीं करूँगा।

+0

दिनांक इनपुट प्रारूप क्या होगा? जवाब उस पर निर्भर करेगा। :) – Jon

+0

मैं सुझावों के लिए खुला हूं। मुझे यकीन नहीं है कि मेरे पास "बीसी/एडीडी" के अतिरिक्त अतिरिक्त ड्रॉप-डाउन की श्रृंखला होगी। या एक साधारण टेक्स्टबॉक्स। – Sampson

+0

नीचे मेरा लंबा जवाब देखें; संक्षेप में, बीसी/एडी ध्वनि के लिए रेडियो बटन मेरे लिए सबसे उपयुक्त हैं। – Jon

उत्तर

5

ध्यान से लिखे गए नियमित अभिव्यक्तियों की एक श्रृंखला के बारे में जो प्रत्येक संभावित प्रारूप को पहचानते हैं। एक बार जब आप प्रारूप को जानते हैं, तो आप इसे मान्य कर सकते हैं और शायद इसे एक समान प्रतिनिधित्व में डाल सकते हैं (उदाहरण के लिए, 64-बिट टाइम_टी)।

जैसे

/(\d{4})-(\d{2})-(\d{2})/ 
/(\d+)(bc|b.c.|bce|b.c.e)/i 
etc. 

यह लग रहा है के बाद से हर रूप की तरह अपनी ही मान्यता नियम हैं, और आप किसी भी व्यापक रूप से उपलब्ध मानक को लागू नहीं कर रहे हैं, मुझे लगता है कि आप प्रत्येक मामले में अलग से मान्य अटक कर रहे हैं।

अद्यतन:

सभी तिथियों अपने वैश्विक सूची के भीतर sortable होना चाहिए।

ऐसा लगता है कि विभिन्न प्रारूपों में दिखाई देने वाली तिथियों को क्रमबद्ध करने में सक्षम होने के लिए आपको आंतरिक रूप से प्रत्येक के लिए एक समान प्रतिनिधित्व की आवश्यकता होगी, जैसा कि मैंने पहले उल्लेख किया था। उदाहरण के लिए, एक बहु-कुंजी शब्दकोश का उपयोग करें (सीडी + में std :: multimap, PHP के बारे में निश्चित नहीं) स्टोर (समान प्रतिनिधित्व) -> (इनपुट प्रतिनिधित्व) मैपिंग्स। कंटेनर के कार्यान्वयन के आधार पर, आपको मुफ्त में रिवर्स लुकअप या कुंजी ऑर्डरिंग मिल सकती है।

-2

स्ट्रेटोटाइम() के बारे में क्या?

+6

मुझे नहीं लगता कि आप पूरे प्रश्न को पढ़ते हैं। –

+0

मैंने किया। स्ट्रेटोटाइम वह दिनांक प्रारूपों के एक हिस्से को मान्य कर सकता है जो वह अपेक्षा करता है। कुछ नियमित अभिव्यक्ति के संबंध में इसका उपयोग करें और आप सेट हैं। – dusoft

+0

हाँ, आगे बढ़ो, मुझे नीचे छोड़ दो, तुम्हारा अहंकार कई राय स्वीकार नहीं कर सकता है। – dusoft

0

मुझे लगता है कि सभी सकारात्मकताएं सूचीबद्ध हैं (या उन्हें किसी भी तरह समूहित करें) और प्रत्येक विकल्प के लिए नियमित अभिव्यक्तियां तैयार करें - और उस आधार पर इसे पहचानें और इसे संभालें।

1

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

कारण यह है कि मैं सुझाव देता हूं कि 200 ईसा पूर्व और 14 9 2-10-07 बहुत अलग हैं, यहां तक ​​कि प्रारूपानुसार भी हैं।कफ को बोलते हुए, यदि आप बीसी एडी का इलाज करते हैं तो आप इसके साथ की गणना भी कर सकते हैं।

2

Zend_Date का उपयोग करने के बारे में क्या। Zend's date library एक बहुत अच्छी तारीख उपयोगिता पुस्तकालय है। यह स्टैंडअलोन या अन्य ज़ेंड लाइब्रेरीज़ के साथ काम कर सकता है और date_default_timezone_set() के साथ काम कर सकता है, इसलिए तारीखों को स्वचालित रूप से सेट टाइमज़ोन के लिए पार्स किया जाता है और यह यूनिक्स टाइमस्टैम्प रेंज के बाहर की तिथियों के लिए काम करेगा। कभी-कभी लिखने के लिए यह थोड़ा लंबा हो सकता है, लेकिन इसकी ताकतें इसकी कमजोरियों से काफी अधिक हैं।

आपको बीसी/एडी के लिए अपना खुद का कस्टम पार्सिंग लागू करना पड़ सकता है क्योंकि मुझे यकीन नहीं है कि यह इसके लिए काम करेगा, लेकिन यह एक कोशिश के लायक हो सकता है।

Pear also has a date library जो कि देखने योग्य हो सकता है, हालांकि, मैंने इसका उपयोग नहीं किया है और बहुत से लोगों से सुना है कि वे पियर के दिनांक पैकेज में ज़ेंड_Date पसंद करते हैं।

आप हमेशा अपना खुद का लिख ​​सकते हैं, लेकिन पहिया का फिर से आविष्कार क्यों करें। यदि यह आपके इच्छित तरीके से रोल नहीं करता है, तो इसे लें और इसमें सुधार करें;)

1

चूंकि आप इनपुट इंटरफ़ेस के नियंत्रण में हैं, सामान्यता के नुकसान के बिना हम मान सकते हैं कि अलग वर्ष/महीना/दिन होगा पूर्णांक (पूर्णांक होने के लिए ठीक से सत्यापित करें :)। मान लीजिए कि बीसी इंगित करने के लिए वर्ष नकारात्मक होगा।

तो सबसे पहले ... स्पष्ट (आंशिक) उत्तर: checkdate()। फ़ंक्शन प्रलेखन के अनुसार यह वर्षों> = 1 के लिए ठीक है।

आप 'इसलिए अगर साल < = 0.

के एक side-trek यहाँ बनाने के लिए और क्यों है कि एक बड़ा समस्या हो सकती है चलो क्या करना है की समस्या से अटक फिर ...

के अनुसार ऊपर विकिपीडिया लिंक, जूलियन कैलेंडर 45 ईसा पूर्व में प्रभावी हुआ। यह कैलेंडर, सभी व्यावहारिक उद्देश्यों के लिए, ग्रेगोरियन कैलेंडर के समान है जिसे हम आज उपयोग करते हैं। अंतर यह है कि उनके बीच दस दिन का ऑफसेट होता है; जूलियन कैलेंडर का अंतिम दिन गुरुवार, 4 अक्टूबर 1582 था और इसके बाद ग्रेगोरियन कैलेंडर के पहले दिन, शुक्रवार, 15 अक्टूबर 1582 (सप्ताहांत का चक्र प्रभावित नहीं हुआ) था।

इसका पहले से ही मतलब है कि 5 अक्टूबर 1582 से 14 अक्टूबर 1582 (समावेशी) की सीमाएं हैं, यदि आप ग्रेगोरियन कैलेंडर का पालन कर रहे हैं; वे कभी अस्तित्व में नहीं हैं।

वहां से पीछे जाकर, आप 45 ईसा पूर्व तक अच्छे हैं। 46 ईसा पूर्व से, जूलियन के बजाय Roman calendar का उपयोग किया गया था।

मैं यहां उस गड़बड़ी में नहीं जा रहा हूं, लेकिन बस उल्लेख करें कि चूंकि यह कैलेंडर ग्रेगोरियन से काफी अलग था, इसलिए आपके उपयोगकर्ता "रोमन कैलेंडर दिनांक इनपुट फॉर्म" देखने के लिए तैयार नहीं होंगे। मेरा सुझाव है, तकनीकी रूप से सही से अपने ऐप को बेहतर बनाने के लिए बेहतर है।

यदि यह माना जा सकता है कि किसी भी व्यक्ति को उनके दिमाग में वास्तव में बीसी तिथि नहीं पता है, या पता है कि इसे ठीक से कैसे निर्दिष्ट किया जाए, तो भी आप यह मान सकते हैं कि सभी तिथियां बीसी फॉर्म 1 के हैं /1 साल। इसलिए आपका इंटरफ़ेस महीने/दिन नियंत्रण अक्षम कर सकता है यदि कोई "बीसी" चेकबॉक्स चेक किया गया था, तो बीसी और एडी के लिए अलग-अलग समूह बॉक्स, या उपयुक्त कुछ भी हो।

इस सब के बाद एकमात्र शेष समस्या, जैसा कि मैंने इसे देखा, लीप वर्षों की तारीखों की जांच कर रहा है। वे introduced with the Julian calendar, but not actually implemented correctly until 8 AD थे।

दस्तावेजों के ऊपर अंतिम लिंक 45 ईसा पूर्व - 4 एडी (समावेशी) लीप वर्षों के दौरान सही ढंग से गणना नहीं की गई थी। एक समारोह है कि कि विसंगति के लिए खातों साल की छलांग है, प्लस जूलियन/ग्रेगोरियन स्विच होगा:

define('YEAR_JULIAN_CALENDAR_INTRODUCED', -45); 
define('YEAR_JULIAN_CALENDAR_LEAP_IMPLEMENTED_CORRECTLY', 8); 
define('YEAR_GREGORIAN_CALENDAR_INTRODUCED', 1582); 

function is_leap_year($year) { 
    if($year < YEAR_JULIAN_CALENDAR_INTRODUCED) { 
     return false; // or good luck :) 
    } 
    if($year < YEAR_JULIAN_CALENDAR_LEAP_IMPLEMENTED_CORRECTLY) { 
     return $year <= -9 && $year % 3 == 0; 
    } 
    if($year < YEAR_GREGORIAN_CALENDAR_INTRODUCED) { 
     return $year % 4 == 0; 
    } 
    // Otherwise, Gregorian is in effect 
    return $year % 4 == 0 && ($year % 100 != 0 || $year % 400 == 0); 
} 

इस के साथ सशस्त्र, आप तो एक समारोह है कि सही ढंग से आपको बताता है कि कितने दिनों वहाँ प्रत्येक में हैं लिख सकता है साल। उस समय तिथि घटाव/अतिरिक्त बनाया जा सकता है।

यह सब चर्चा के बाद (मैं किसी को जो इतनी दूर :) मैं पूछने के लिए पढ़ा है की हिम्मत की प्रशंसा करते हैं:

सटीकता कितना आप वास्तव में जरूरत है?

आप तय करते हैं कि आप "तकनीकी जानकारी" के बारे में गुदा होने की जरूरत है, मैं व्यक्तिगत रूप से काम करता है जैसा कि ऊपर उल्लेख लागू होगा, और फिर यदि: क) मेरी दस्तकारी तारीख पुस्तकालय के रूप में उनका उपयोग करें या ख) की जांच करने के लिए उनका उपयोग करें कि में दिलचस्पी रखने वाली कोई भी 3-पार्टी पार्टी लाइब्रेरी वास्तव में सही ढंग से लागू की गई है।

यदि आपको ऐसा करने की आवश्यकता नहीं है, तो बस दिखाएं कि आप इसे कभी नहीं पढ़ते हैं। :)

+0

यह अनिवार्य रूप से इस आवेदन के विकास में शामिल किसी अन्य व्यक्ति के साथ एक लंबी चर्चा की सामग्री है। अंत में, हमने उपयोगकर्ताओं को अपनी तिथियों को कैलिब्रेट करने का फैसला किया :) – Sampson

0

दूसरा जवाब, जोनाथन के सवाल का अद्यतन करने के बाद:

सीधा तारीख तुलना के लिए, आप d कुछ पूर्णांक की तरह उपयोग करने के लिए या एक वर्ग पुस्तकालय (मुझे नहीं पता कि दिनांक 9999 ईसा पूर्व के लिए वापस समर्थन करता है, जरूरत है, एक के बारे में पता है)।

आप 1/1/10000 ईसा पूर्व (अपने स्वयं के युग रोल) के बाद से सेकंड की संख्या के रूप में बस निर्दिष्ट कर सकते हैं; इसके लिए 64 बिट्स पर्याप्त से अधिक होंगे। ऐसा करने के लिए, आपको एक या दो समस्याओं को हल करने की आवश्यकता है।

ए PHP में 64-बिट इन्स कैसे करें।

PHP पूर्णांक के लिए 31 बिट प्रदान करने की गारंटी है। इसलिए आप निम्न में से एक कर सकता है:

  1. अपने स्वयं के 62-बिट-पूर्णांक वर्ग है, जो दो निजी पूर्णांक सदस्यों में बिट्स संग्रहीत करता लिखें। 62 बिट्स पर्याप्त से भी अधिक हैं।

    यह दर्दनाक और शायद तेज़ होगा। प्रमुख लाभ: आप किसी भी PHP एक्सटेंशन पर निर्भर नहीं होंगे।

  2. मनमाने ढंग से सटीक पूर्णांक करने के लिए BCMath या GMP का उपयोग करें।

    पोर्टेबिलिटी जरूरी नहीं है, तो मैं इसे पहले कोशिश करूँगा। यह स्वीकार्य से धीमा साबित हो सकता है, यद्यपि। प्रमुख लाभ: आपको बिट-फिडलिंग कोड गलत होने का जोखिम नहीं है।

हाथ में 60 या तो बिट-पूर्णांक वर्ग के साथ (इसी तरीके या सहायक कार्यों के माध्यम से समर्थन अलावा/घटाव/तुलना), इसके बाद आपको एक CustomDateTime वर्ग जो आपके सभी आवश्यक तर्क का समर्थन करता है लिख सकते हैं । इस वर्ग में सभी "डेट-टू-इंट" और इसके विपरीत कोड (जैसे निर्माण) शामिल होंगे; सभी को-पूरी तरह से करने के लिए-int-int-कार्यान्वयन संचालन (उदा। तुलना) को आपके पूर्णांक वर्ग में अग्रेषित किया जाएगा।

बी डेटाबेस में 64-बिट इन्स कैसे करें।

सभी डेटाबेस बिना किसी समस्या के करते हैं। हालांकि आपको लगभग निश्चित रूप से इस मार्ग पर जाना होगा, क्योंकि उदा। MySQL 1000 ईस्वी से पहले तिथियों का समर्थन नहीं करता है। अन्य विक्रेताओं के बारे में नहीं जानते।

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