2012-08-29 13 views
5

मैं सोच रहा था कि कोई अंतर्निर्मित पर्ल फ़ंक्शन है जो तिथि को समायोजित करता है यदि आप इससे एक महीने लेते हैं। जैसे यदि तिथि 31 है, तो यह पिछले महीने के अंत में समायोजित होगी यदि उसके पास 31 दिन नहीं हैं।पर्ल में महीने में अलग-अलग दिनों का खाता लेने के महीनों में वापस कैसे जाना है?

यदि मैं एक दूसरे के बाद 31 दिनों (दिसंबर/जनवरी, जुलाई/अगस्त) और फरवरी के महीनों के लिए नहीं था, तो मैं इसे 30 वें स्थान पर बदल सकता हूं। मैं बस तारीख को एक निश्चित मात्रा से वर्तमान तारीख से दूर करना चाहता हूं, उदा।

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); 

$current_date = join("-", (1900+$year), ($mon+1), $mday); 
$one_month_ago = join("-", (1900+$year), ($mon), $mday); 
$one_year_ago = join("-", (1899+$year), ($mon+1), $mday); 

मैं फरवरी उदाहरण के साथ सौदा कर सकते हैं, क्योंकि यह केवल वर्ष के लिए लागू होता है, लेकिन अगर यह 31 वें दिसंबर 2012 को लिया गया था तो एक महीने दूर ले मतलब होगा 31 वें नवंबर 2012, जो निश्चित रूप से मौजूद नहीं था। मैंने सोचा था कि अगर कोई खुद के लिए चीजें उलझी से पहले एक समारोह था मैं पूछना होगा ... धन्यवाद :)

+2

[डेटटाइम] (https://metacpan.org/module/DateTime) शायद आप इस मॉड्यूल को खोज सकते हैं? (इसकी तारीख 'गणित है) – gaussblurinc

+0

दोनों नीचे अच्छे जवाब! दिनांक समय वास्तव में उपयोगी विकल्प की तरह दिखता है, लेकिन जैसा कि मैं इसे अपने कोड के एक छोटे से हिस्से के लिए उपयोग करना चाहता हूं, मुझे लगता है कि मैं बस इसमें डुबकी लगा सकता हूं और इसके लिए क्लॉज का एक गुच्छा बना सकता हूं। लंबे समय तक घुमाया गया, लेकिन यह मुझे सीखने में मदद करेगा ... यह मेरा पहला दिन पर्ल का उपयोग कर रहा है: पी आपकी मदद के लिए धन्यवाद! – dgBP

उत्तर

8

दूसरों DateTime का सुझाव दिया है, लेकिन यह काफी बड़ी, गैर-प्रमुख है, और धीमी गति से हो सकता है।

एक बहुत सरल समाधान निर्मित localtime और POSIX::mktime कार्यों का उपयोग करने के लिए है:

use POSIX qw(mktime); 

my @t = localtime $epoch; 
$t[4] -= 2; # $t[4] is tm_mon 
my $two_months_ago = mktime @t; 

mktime() समारोह विशेष रूप से denormalised मूल्यों संभालती है; यह इस तथ्य से निपटने के लिए होगा कि जैनुररी शून्य 2 महीने पिछले वर्ष नवंबर है, आदि .. यह दिन का एक ही दूसरा/मिनट/घंटा और महीने के उसी दिन रखेगा।

+0

यह बहुत अच्छा लग रहा है, लेकिन मैं इसे $ 2_months_ago आकृति को मुद्रित करने के लिए नहीं प्राप्त कर सकता क्योंकि यह कहता है कि यह अनियमित है (मैंने तब इसे बिना किसी परिवर्तन के आरंभ किया)। – dgBP

+0

मेरे लिए काम करता है: http://pastie.org/4610603 – LeoNerd

+0

उस अन्य कोड के साथ यह वास्तव में करता है! मुझे यह कहना है कि यह एक बेहतर संस्करण है जिसे मैं ढूंढ रहा था :) kudos – dgBP

10

दिनांक समय नहीं निर्मित एक मॉड्यूल है, लेकिन एक बार आप इसे स्थापित किया है है, यह इस गणित तुच्छ बनाता है:

#!/usr/bin/perl 
use strict; 
use warnings; 

use feature qw(say); 
use DateTime; 

my $dt = DateTime->now; 
say $dt->ymd; 

$dt->truncate(to => month); 

say $dt->ymd; 

$dt->add(days => -1); 
say $dt->ymd; 

foreach (1 .. 12) { 
    $dt->add(months => -1); 
    say $dt->ymd; 
} 

जब मैं यह आज चलाने (अगस्त 29, 2012) मैं निम्नलिखित उत्पादन प्राप्त करें:

[~] $ perl dt.pl 
2012-08-29 
2012-08-01 
2012-07-31 
2012-06-30 
2012-05-31 
2012-04-30 
2012-03-31 
2012-02-29 
2012-01-31 
2011-12-31 
2011-11-30 
2011-10-31 
2011-09-30 
2011-08-31 
2011-07-31 
+0

ईमानदारी से, अगर मैं दो सर्वश्रेष्ठ उत्तर दे सकता हूं, लेकिन आपको थोड़ा और जानकारी मिल गई है :) धन्यवाद! मैंने कभी भी यह सुविधा नहीं देखी है - यह जानना उपयोगी है! – dgBP

+0

यह सुविधा पर्ल के संस्करण पर निर्भर करती है। यह होना चाहिए> = 5.10 –

7

आप मॉड्यूल DateTime स्थापित करने के लिए एक मौका है। जब आप तिथियों से निपटते हैं तो यह आपके बहुत सारे लाभ देता है।

use strict; 
use DateTime; 

my $epoch = ...; 
my $dt = DateTime->from_epoch(epoch => $epoch); 
$dt->subract(months => 1); 

printf "%s", $dt->datetime(); 
+0

अच्छा, धन्यवाद! :) – dgBP