2008-09-18 21 views
36

एक तिथि/समय (वर्ष, महीना, दिन, घंटा, मिनट, सेकंड) की सरणी के रूप में देखते हुए, आप इसे युग के समय में कैसे परिवर्तित करेंगे, यानी, 1 9 70-01-01 00:00 से सेकंड की संख्या: 00 जीएमटी?पर्ल में मैं दिनांक/समय को युग समय (यूनिक्स समय/सेकंड से 1 9 70) में कैसे परिवर्तित करूं?

बोनस प्रश्न: यदि किसी स्ट्रिंग के रूप में दिनांक/समय दिया गया है, तो आप इसे पहले (y, m, d, h, m, s) सरणी में कैसे पार्स करेंगे?

+1

इस प्रश्न में अजीब वोट नीचे – jdelator

+2

Obligatory चेतावनी है: यूनिक्स Epoch केवल 1 901 - 2038 के लिए परिभाषित किया गया है। – Piskvor

+5

@Piskvor: यह सख्ती से सच नहीं है। और युग को 1 जनवरी 1 9 70 के रूप में परिभाषित किया गया है, न कि एक सीमा। हालांकि, यदि आप 32-बिट पूर्णांक (जो व्यापक सम्मेलन है) में इसका प्रतिनिधित्व करते हैं तो यूनिक्स टाइमस्टैम्प के लिए आपको सबसे अच्छी रेंज मिल जाएगी। –

उत्तर

19

यह सबसे आसान तरीका है यूनिक्स समय प्राप्त करने के लिए है:

use Time::Local; 
timelocal($second,$minute,$hour,$day,$month-1,$year); 

नोट तर्क के विपरीत क्रम और कि जनवरी माह 0. है कई और अधिक विकल्पों के लिए, CPAN से DateTime मॉड्यूल देखें।

पार्सिंग के लिए, Date::Parse सीपीएएन से मॉड्यूल देखें। यदि आपको वास्तव में तारीख पार्सिंग के साथ फैंसी प्राप्त करने की आवश्यकता है, तो Date::Manip सहायक हो सकता है, हालांकि इसका स्वयं का दस्तावेज आपको इससे दूर चेतावनी देता है क्योंकि इसमें बहुत सामान है (यह सामान्य व्यवसाय छुट्टियों जैसी चीजें जानता है, उदाहरण के लिए) और अन्य समाधान बहुत अधिक हैं और तेज।

यदि आपको दिनांक/समय के प्रारूप के बारे में कुछ पता होना है तो आप पार्सिंग करेंगे तो एक साधारण नियमित अभिव्यक्ति पर्याप्त हो सकती है लेकिन आप संभवतः उपयुक्त CPAN मॉड्यूल का उपयोग बंद कर सकते हैं। उदाहरण के लिए, यदि आप जानते हैं कि तिथियां हमेशा वाईएमडीएचएमएस ऑर्डर में होंगी, तो सीपीएएन मॉड्यूल DateTime::Format::ISO8601 का उपयोग करें।


मेरे अपने संदर्भ के लिए, यदि और कुछ नहीं, नीचे एक समारोह मैं एक आवेदन जहाँ मैं पता दिनांकों हमेशा सभी या "एचएमएस" भाग वैकल्पिक का हिस्सा साथ YMDHMS क्रम में हो जाएगा के लिए इस्तेमाल करते हैं। यह किसी भी delimiters स्वीकार करता है (उदाहरण के लिए, "2009-02-15" या "2009.02.15")। यह संबंधित यूनिक्स समय (1 9 70-01-01 00:00:00 जीएमटी के बाद से सेकंड) देता है या -1 यदि यह इसे पार्स नहीं कर सका (जिसका मतलब है कि आप बेहतर सुनिश्चित करते हैं कि आपको कभी भी वैधता को दिनांक 1 9 6 9- 12-31 23:59:59)। यह "20XX" तक "6 9" तक दो अंकों के एक्सएक्स को भी मानता है, अन्यथा "1 9XX" (उदाहरण के लिए, "50-02-15" का अर्थ 2050-02-15 है, लेकिन "75-02-15" का मतलब है 1 9 75- 02-15)।

use Time::Local; 

sub parsedate { 
    my($s) = @_; 
    my($year, $month, $day, $hour, $minute, $second); 

    if($s =~ m{^\s*(\d{1,4})\W*0*(\d{1,2})\W*0*(\d{1,2})\W*0* 
       (\d{0,2})\W*0*(\d{0,2})\W*0*(\d{0,2})}x) { 
    $year = $1; $month = $2; $day = $3; 
    $hour = $4; $minute = $5; $second = $6; 
    $hour |= 0; $minute |= 0; $second |= 0; # defaults. 
    $year = ($year<100 ? ($year<70 ? 2000+$year : 1900+$year) : $year); 
    return timelocal($second,$minute,$hour,$day,$month-1,$year); 
    } 
    return -1; 
} 
+0

समय :: स्थानीय आपको क्या लाभ देता है कि अधिक आम POSIX (strftime) नहीं करता है? –

+3

स्ट्रेटटाइम समय आउटपुट के लिए है, टाइमलोकल उन्हें 'इनपुट' करना है। शून्य सूचकांक महीने के लिए –

+1

$ महीना -1 !!!!!! मैं फिर से भूलने की कोशिश नहीं करूंगा। –

33

आप DateTime मॉड्यूल का उपयोग कर रहे हैं, तो आप, दिनांक समय वस्तु पर epoch() विधि कॉल कर सकते हैं के बाद से क्या आप यूनिक्स समय के रूप में के बारे में सोच है कि।

डेटटाइम्स का उपयोग करके आप युग से आज तक वस्तुओं को आसानी से परिवर्तित कर सकते हैं।

Alternativly, localtime और gmtime Time::Local module से दिन महीने और वर्ष, और timelocal और timegm युक्त एक सरणी में एक युग परिवर्तित, विपरीत करना होगा समय तत्वों की एक सरणी परिवर्तित (सेकंड, मिनट, ..., दिन , महीनों आदि) एक युग में।

+0

अपने स्वयं के (बग्गी) समाधान को रोल करने के बजाय एक सामान्य ऑपरेशन करने के लिए लाइब्रेरी फ़ंक्शन का उपयोग करना हमेशा बेहतर होता है। –

+0

नीचे 'टाइमेलोकल' समाधान बेहतर है क्योंकि डेटटाइम मानक पर्ल इंस्टॉलेशन –

-4

यदि आप केवल एक कमांड लाइन उपयोगिता की तलाश में हैं (यानी, ऐसा कुछ नहीं जो अन्य कार्यों से बुलाया जाएगा), इस स्क्रिप्ट को आजमाएं। यह जीएनयू तारीख के अस्तित्व को मानता (काफी किसी भी Linux सिस्टम पर):

#! /usr/bin/perl -w 

use strict; 

$_ = (join ' ', @ARGV); 
$_ ||= <STDIN>; 

chomp; 

if (/^[\d.]+$/) { 
    print scalar localtime $_; 
    print "\n"; 
} 
else { 
    exec "date -d '$_' +%s"; 
} 

यहाँ यह कैसे काम करता है:

$ Time now 
1221763842 

$ Time yesterday 
1221677444 

$ Time 1221677444 
Wed Sep 17 11:50:44 2008 

$ Time '12:30pm jan 4 1987' 
536790600 

$ Time '9am 8 weeks ago' 
1216915200 
+0

का हिस्सा नहीं है, यह ऐसी चीज है जो या तो खोल स्क्रिप्ट होनी चाहिए, या इसे काम करने के लिए उचित पर्ल मॉड्यूल का उपयोग करने के लिए किया जाना चाहिए IMHO । –

+0

इसे एक शेल स्क्रिप्ट के रूप में क्यों लिखें? यह ठीक काम करता है और मुझे दैनिक आधार पर यह बेहद उपयोगी लगता है। – raldi

+0

एक perl समाधान नहीं है अगर यह सिस्टम दिनांक कमांड पर निर्भर करता है। यूनिक्स या विंडोज़ में काम नहीं करता है। – kkoolpatz

16

एक तारीख को पार्स करने के लिए, CPAN में Date::Parse को देखो।

-3

एक फ़िल्टर विभिन्न आईएसओ से संबंधित प्रारूपों में किसी भी तारीख को परिवर्तित कर रहा है (और ताकतवर कुह्न के the writings पढ़ने के बाद कुछ और उपयोग कौन करेगा?) को मानक इनपुट पर सेकंड के बाद से-युग मानक आउटपुट पर समय दोनों भागों को वर्णन करने की सेवा कर सकता है:

[email protected]:~$ cat `which isoToEpoch` 
#!/usr/bin/perl -w 
use strict; 
use Time::Piece; 
# sudo apt-get install libtime-piece-perl 
while (<>) { 
    # date --iso=s: 
    # 2007-02-15T18:25:42-0800 
    # Other matched formats: 
    # 2007-02-15 13:50:29 (UTC-0800) 
    # 2007-02-15 13:50:29 (UTC-08:00) 
    s/(\d{4}-\d{2}-\d{2}([T ])\d{2}:\d{2}:\d{2})(?:\.\d+)? ?(?:\(UTC)?([+\-]\d{2})?:?00\)?/Time::Piece->strptime ($1, "%Y-%m-%d$2%H:%M:%S")->epoch - (defined ($3) ? $3 * 3600 : 0)/eg; 
    print; 
} 
[email protected]:~$ 
2

मेरा पसंदीदा datetime पार्सर DateTime::Format::ISO8601 एक बार जब आप काम कर रहे है कि मिल गया है, तो आप एक दिनांक समय होगा है वस्तु, आसानी से convertable युग के साथ सेकंड()

6

Get Date::Manip from CPAN युग है, तो:

use Date::Manip; 
$string = '18-Sep-2008 20:09'; # or a wide range of other date formats 
$unix_time = UnixDate(ParseDate($string), "%s"); 

संपादित करें:

दिनांक :: Manip मैं बड़ा और धीमा, लेकिन पार्सिंग में बहुत लचीला है, और यह शुद्ध perl है। अगर आप कोड लिख रहे हों तो जल्दी में हों, और आप जानते हैं कि जब आप इसे चला रहे हों तो आप जल्दबाजी में नहीं होंगे।

उदा। स्टार्ट-अप पर एक बार कमांड लाइन विकल्पों को पार्स करने के लिए इसका इस्तेमाल करें, लेकिन व्यस्त वेब सर्वर पर बड़ी मात्रा में डेटा पार्स करने का उपयोग न करें।

the authors comments देखें।

+6

नहीं, कृपया नहीं। तिथि :: मणिप के अपने दस्तावेज़ में एक बड़ा खंड है जो आपको यह समझाने की कोशिश करता है कि इसका उपयोग न करें। –

+2

दिनांक :: जब आप सबसे कमजोर होते हैं तो मणिप आपको धोखा देगी। डेटटाइम का प्रयोग करें। :) – Kevin

+0

@AristotlePagaltzis, जहां "आपको इसका उपयोग न करने के लिए मनाने की कोशिश करता है" का अर्थ केवल "कहता है कि यह एक कैलेंडर के साथ सबकुछ कर सकता है, लेकिन यह अनुमति देता है कि कई अन्य मॉड्यूल कई अन्य मॉड्यूल द्वारा अधिक कुशलता से किया जा सकता है।" तो, सब कुछ स्कॉटक पहले से ही कहता है, तिथि :: मणिप पर एक और स्टॉप समाधान पर अधिक जोर देने के साथ। –

2
संभवतः

'का वहाँ एक से अधिक तरीका यह करना है बेहतर उदाहरणों में से एक ", के साथ या CPAN की मदद के बिना (नीचे पहली टिप्पणी के लेखक के लिए धन्यवाद)।

हैं आपके पास 'दिनांक/समय' के रूप में पारित होने पर नियंत्रण होता है, मैं DateTime मार्ग पर जाने का सुझाव देता हूं, या तो एक विशिष्ट दिनांक :: समय :: प्रारूप सबक्लास का उपयोग करके या डेटटाइम :: प्रारूप :: स्ट्रिपटाइम का उपयोग करके कोई भी आपकी निराशाजनक तिथि प्रारूप का समर्थन नहीं कर रहा है (अधिक जानकारी के लिए datetime FAQ देखें)। सामान्यतः, तिथि :: समय का तरीका यह है कि आप परिणाम के साथ गंभीर कुछ करना चाहते हैं: सीपीएएन पर कुछ कक्षाएं गुदा- प्रतिधारण और जुनूनी जीवंत सटीक

तुम अजीब freeform सामान की उम्मीद कर रहे हैं, तो Date::Parse के str2time() विधि में फेंक, आप एक सेकंड के बाद से-युग मूल्य आप तो साथ अपने दुष्ट रास्ता हो सकता है मिल which'll Date::Manip की भूमि के ऊपर के बिना ।

2

सीपीएएन पर कई डेट मैनिपुलेशन मॉड्यूल हैं। मेरा विशेष पसंदीदा DateTime है और आप strptime modules का उपयोग मनमाने ढंग से प्रारूपों में पार्स करने के लिए कर सकते हैं। विशिष्ट डेट प्रारूपों को संभालने के लिए सीपीएएन पर कई डेटटाइम :: प्रारूप मॉड्यूल भी हैं, लेकिन स्ट्रेटटाइम सबसे सामान्य है।

7
$ENV{TZ}="GMT"; 
POSIX::tzset(); 
$time = POSIX::mktime($s,$m,$h,$d,$mo-1,$y-1900); 
+0

युग का समय पहले ही जीएमटी में है, वहां कोई टाइमज़ोन नहीं है। टीजेड = जीएमटी को स्पष्ट रूप से सेट करके, क्या आप स्थानीय दिनांक/समय की बजाय ** जीएमटी टाइमज़ोन ** से ** के रूप में पार्सिंग नहीं कर रहे हैं? (और मुझे लगता है कि आपको टीजेड = यूटीसी का उपयोग करना चाहिए, जीएमटी एक देश का टाइमज़ोन है) –

+0

@ थॉमसगुयोट-सियोननेस्ट मेरा इरादा यह वर्णन करना था कि एमकेटाइम स्थानीय समय से युग सेकेंड में परिवर्तित हो जाता है, इसलिए आपको यह जानने की जरूरत है कि आपका इनपुट किस समय स्थानीय है और तदनुसार टीजेड सेट करें (या बस मान लें कि टीजेड पहले से ही आप जो चाहते हैं उसे सेट कर चुका है, लेकिन यह मैला है) – ysth

+0

मुझे लगता है कि ज्यादातर लोगों को लगता है कि ज्यादातर लोग स्थानीय समय का उपयोग करना चाहते हैं और यह कंप्यूटर/सर्वर पर सेट है। मैं समझता हूं कि विभिन्न क्षेत्रों के साथ काम करते समय ज़ोन महत्वपूर्ण है, लेकिन मुझे लगता है कि जीएमटी को टीजेड को वास्तविक उत्तर से परेशान करने का उदाहरण दिखा रहा है और समय इनपुट के लिए गलत टाइमज़ोन का उपयोग करने में रूकी को भी गुमराह कर सकता है। ओटीओएच आपको टीजेड बदलने के बाद tzset() को कॉल करने के लिए बोनस प्वाइंट मिलता है;) –

2
आगे के संदर्भ के लिए

, एक एक लाइनर कि, में लागू किया जा सकता उदाहरण के लिए, !#/bin/sh स्क्रिप्ट।

EPOCH="`perl -e 'use Time::Local; print timelocal('${SEC}','${MIN}','${HOUR}','${DAY}','${MONTH}','${YEAR}'),\"\n\";'`" 

बस ऑक्टल मानों से बचने के लिए याद रखें!

+0

जब आप असीमित रूप से अधिक लचीली जीएनयू तिथि का उपयोग कर सकते हैं तो पर्ल का उपयोग क्यों करें? "दिनांक-डी" STRING "+% s'" कल "से" 9 0 दिनों "[अभी के बाद]" मार्च 15 2016 "जैसी अधिक पारंपरिक चीजों के लिए लगभग कुछ भी अनुमति देता है और लगभग किसी प्रारूप में भी आउटपुट कर सकता है (' +% s' युग है, और अधिक के लिए 'date --help' देखें)। (यह बहुत खराब है 'डेटटाइम' में यह कार्यक्षमता नहीं है।) –

7

मुझे पता है कि यह एक पुराना सवाल है, लेकिन सोचा कि मैं एक और जवाब दूंगा।

Time::Piece पर्ल 5.9.5

के रूप में मूल है यह strptime विधि के माध्यम से मनमाना स्वरूपों में समय की पार्स अनुमति देता है।

उदा .:

my $t = Time::Piece->strptime("Sunday 3rd Nov, 1943", 
           "%A %drd %b, %Y"); 

उपयोगी हिस्सा है - क्योंकि यह एक अतिभारित वस्तु है, तो आप संख्यात्मक तुलना के लिए उपयोग कर सकते हैं।

उदा।

if ($t < time()) { #do something } 

या यदि आप यह एक स्ट्रिंग संदर्भ में का उपयोग:

print $t,"\n"; 

आप मिल:

Wed Nov 3 00:00:00 1943 

एक्सेसर तरीकों कि कुछ मिश्रित अन्य उपयोगी समय आधारित रूपांतरण के लिए अनुमति देने का एक समूह है । https://metacpan.org/pod/Time::Piece

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