كيف يمكنني تحويل التاريخ/الوقت إلى وقت العصر (وقت/ثواني يونكس منذ عام 1970) في بيرل؟

StackOverflow https://stackoverflow.com/questions/95492

سؤال

بالنظر إلى التاريخ/الوقت كصفيف من (السنة، الشهر، اليوم، الساعة، الدقيقة، الثانية)، كيف يمكنك تحويله إلى وقت العصر، أي عدد الثواني منذ 1970-01-01 00:00:00 بتوقيت جرينتش ؟

السؤال مكافأة:إذا أعطيت التاريخ/الوقت كسلسلة، فكيف يمكنك تحليله أولاً في المصفوفة (y,m,d,h,m,s)؟

هل كانت مفيدة؟

المحلول 2

هذه هي أبسط طريقة للحصول على وقت يونكس:

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

لاحظ الترتيب العكسي للوسائط وأن شهر يناير هو الشهر 0.لمزيد من الخيارات، راجع التاريخ والوقت وحدة من CPAN.

أما بالنسبة للتحليل، فانظر التاريخ::تحليل وحدة من CPAN.إذا كنت حقًا بحاجة إلى التعمق في تحليل التاريخ، فإن التاريخ::مانيب قد يكون مفيدًا، على الرغم من أن الوثائق الخاصة به تحذرك منه نظرًا لأنه يحمل الكثير من الأمتعة (فهو يعرف أشياء مثل عطلات العمل الشائعة، على سبيل المثال) والحلول الأخرى أسرع بكثير.

إذا كنت تعرف شيئًا ما عن تنسيق التاريخ/الأوقات التي ستقوم بتحليلها، فقد يكفي تعبير عادي بسيط ولكن ربما يكون من الأفضل لك استخدام وحدة CPAN المناسبة.على سبيل المثال، إذا كنت تعلم أن التواريخ ستكون دائمًا بترتيب YMDHMS، فاستخدم وحدة CPAN التاريخ والوقت::التنسيق::ISO8601.


كمرجع خاص بي، إذا لم يكن هناك أي شيء آخر، فيما يلي وظيفة أستخدمها لتطبيق أعرف أن التواريخ ستكون دائمًا بترتيب YMDHMS مع كل جزء "HMS" أو جزء منه اختياري.ويقبل أي محددات (على سبيل المثال، "2009-02-15" أو "2009.02.15").تقوم بإرجاع وقت يونكس المقابل (الثواني منذ 00:00:00 بتوقيت جرينتش) أو -1 إذا لم تتمكن من تحليله (مما يعني أنه من الأفضل أن تتأكد من أنك لن تحتاج أبدًا بشكل قانوني إلى تحليل التاريخ 1969- 12-31 23:59:59).كما تفترض أيضًا السنوات المكونة من رقمين XX حتى "69" تشير إلى "20XX"، وإلا فإن "19XX" (على سبيل المثال، "50-02-15" تعني 2050-02-15 لكن "75-02-15" تعني 1975- 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;
}

نصائح أخرى

إذا كنت تستخدم التاريخ والوقت الوحدة، يمكنك الاتصال بـ عصر () الطريقة على كائن DateTime، نظرًا لأن هذا هو ما تعتقد أنه وقت يونكس.

يتيح لك استخدام DateTimes التحويل بسهولة من كائنات العصر إلى كائنات التاريخ.

بدلا من ذلك، الوقت المحلي وسيقوم gmtime بتحويل حقبة إلى مصفوفة تحتوي على يوم وشهر وسنة وtimelocal وtimegm من الوقت::الوحدة المحلية سيفعل العكس، حيث يحول مجموعة من عناصر الوقت (الثواني، الدقائق، ...، الأيام، الأشهر وما إلى ذلك) إلى حقبة.

لتحليل التاريخ، انظر إلى التاريخ::تحليل في شبكة سي بان.

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

أعلم أن هذا سؤال قديم، لكنني أعتقد أنني سأقدم إجابة أخرى.

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

الحصول على التاريخ::Manip من CPAN, ، ثم:

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

يحرر:

Date::Manip كبير وبطيء، ولكنه مرن جدًا في التحليل، وهو عبارة عن لغة Perl خالصة.استخدمه إذا كنت في عجلة من أمرك عندما تكتب التعليمات البرمجية، وأنت تعلم أنك لن تكون في عجلة من أمرك عندما تقوم بتشغيله.

على سبيل المثالاستخدمه لتحليل خيارات سطر الأوامر مرة واحدة عند بدء التشغيل، لكن لا تستخدمه لتحليل كميات كبيرة من البيانات على خادم ويب مشغول.

يرى تعليقات المؤلفين.

(شكرًا لصاحب التعليق الأول أدناه)

محلل التاريخ والوقت المفضل لدي هو التاريخ والوقت::التنسيق::ISO8601 بمجرد الانتهاء من ذلك، سيكون لديك كائن DateTime، يمكن تحويله بسهولة إلى ثواني Epoch باستخدام Epoch()

هناك العديد من وحدات معالجة التاريخ في CPAN.مفضلتي الخاصة هي التاريخ والوقت ويمكنك استخدام وحدات strptime لتحليل التواريخ بتنسيقات عشوائية.هناك أيضًا العديد من وحدات DateTime::Format في CPAN للتعامل مع تنسيقات التاريخ المتخصصة، ولكن strptime هو الأكثر عمومية.

لمزيد من المرجع، بطانة واحدة يمكن تطبيقها، على سبيل المثال، !#/bin/sh نصوص.

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

فقط تذكر أن تتجنب القيم الثمانية!

ربما يكون أحد أفضل الأمثلة على "هناك أكثر من طريقة للقيام بذلك"، بمساعدة أو بدون مساعدة CPAN.

إذا كان لديك سيطرة على ما يتم تمريره كـ "تاريخ/وقت"، فأنا أقترح الانتقال إلى التاريخ والوقت المسار، إما باستخدام فئة فرعية معينة من Date::Time::Format، أو باستخدام DateTime::Format::Strptime إذا لم يكن هناك تنسيق يدعم تنسيق التاريخ الغريب الخاص بك (راجع الأسئلة الشائعة حول التاريخ والوقت لمزيد من التفاصيل).بشكل عام، Date::Time هو الحل الأمثل إذا كنت تريد القيام بأي شيء جدي يؤدي إلى النتيجة:هناك عدد قليل من الفصول في CPAN تتسم بالقدرة على الاحتفاظ بالشرج والدقة الشديدة.

إذا كنت تتوقع أشياء حرة غريبة، قم برميها التاريخ::تحليلطريقة str2time() الخاصة بـ ، والتي ستمنحك قيمة ثانية منذ عصر يمكنك بعد ذلك أن تسلك طريقك الشرير، دون تحمل أي تكاليف إضافية التاريخ::مانيب.

مرشح يحول أي تواريخ بتنسيقات مختلفة متعلقة بـ ISO (ومن سيستخدم أي شيء آخر بعد القراءة الكتابات من Mighty Kuhn؟) على الإدخال القياسي للثواني منذ العصر على الإخراج القياسي قد يساعد في توضيح كلا الجزأين:

martind@whitewater:~$ 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;
}
martind@whitewater:~$ 

إذا كنت تبحث فقط عن أداة مساعدة لسطر الأوامر (أي ليست شيئًا يمكن استدعاؤه من وظائف أخرى)، فجرّب هذا البرنامج النصي.يفترض وجود تاريخ GNU (موجود في أي نظام 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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top