लिनक्स, डीएसटी-सेफ पर कलश में कल की तारीख प्राप्त करें


158

मेरे पास एक शेल स्क्रिप्ट है जो लिनक्स पर चलता है और YYYY-MM-DDप्रारूप में कल की तारीख पाने के लिए इस कॉल का उपयोग करता है :

date -d "1 day ago" '+%Y-%m-%d'

यह ज्यादातर समय काम करता है, लेकिन जब कल सुबह स्क्रिप्ट चली 2013-03-11 0:35 CDTतो "2013-03-09"इसके बजाय वापस लौट आया "2013-03-10"

संभवतः दिन के समय की बचत का समय (जो कल शुरू हुआ था) दोष देना है। मुझे लग रहा है कि जिस तरह "1 day ago"से इसे 24 घंटे घटाया गया है, और 24 घंटे पहले लागू किया 2013-03-11 0:35 CDTगया था 2013-03-09 23:35 CST, जिसके परिणामस्वरूप परिणाम आया "2013-03-09"

तो लिनक्स पर कल की तारीख पाने के लिए एक अच्छा डीएसटी-सुरक्षित तरीका क्या है?


क्या आप इसे हमेशा एक ही समय पर चला रहे हैं, क्या आप इसे बार-बार चला रहे हैं?
tink

@ यह रोजाना 00:35
Ike वाकर

जवाबों:


267

मुझे लगता है कि यह काम करना चाहिए, भले ही आप इसे कितनी बार और कब चलाएं ...

date -d "yesterday 13:00" '+%Y-%m-%d'

1
आप इसे बाद में उपयोग के लिए एक चर में कैसे प्रदान करेंगे?
अशक्त

6
@null - उसी तरह आप किसी अन्य शेल कमांड के आउटपुट को असाइन करेंगे। चर = $ (तारीख -d "कल 13:00" '+% Y-% m-% d') ...
tink

GNU-date के लिए:date -d yesterday 13:00 -I
gogstad

यह इस तथ्य पर निर्भर करता है कि गर्मियों और सर्दियों के समय के बीच स्विचिंग हमेशा रात के दौरान की जाती है, अगर मैं सही ढंग से समझूं?
निकोलस राउल

2
@ नाइकोलासौर: इसकी गारंटी नहीं है; लेकिन यह सुबह में इसे शेड्यूल करने के लिए एक व्यापक रूप से पालन किया जाने वाला सम्मेलन है। दूसरी ओर, आईआईआरसी कोई जगह नहीं है जहां स्विच स्थानीय दोपहर के करीब होगा। तो, "1300J एक डीएसटी सीमा पर कभी नहीं है" एक उचित धारणा है
पिस्कोर ने बिल्डिंग

56

मैक OSX के तहत तारीख थोड़ी अलग है।

कल के लिए

date -v-1d +%F

पिछले हफ्ते के लिए

date -v-1w +%F

8
यदि OSX के भीतर GNU शैली का उपयोग करने में रुचि है, तो आप भी उपयोग कर सकते हैं gdate, homebrew के coreutilsपैकेज में उपलब्ध है ।
user456584

11
आप का मतलब dateअलग है।
अगस्तुर

12

यह भी काम करना चाहिए, लेकिन शायद यह बहुत अधिक है:

date -d @$(( $(date +"%s") - 86400)) +"%Y-%m-%d"

इस तरह की जरूरत है अगर आपको मैक ओएस एक्स से निपटने की जरूरत है dateजो yesterdayवाक्यविन्यास का समर्थन नहीं करता है ...
मिको रानाल्टेनन

7

यदि आप निश्चित हैं कि स्क्रिप्ट दिन के पहले घंटों में चलती है, तो आप बस कर सकते हैं

  date -d "12 hours ago" '+%Y-%m-%d'

BTW, यदि स्क्रिप्ट प्रतिदिन 00:35 (crontab के माध्यम से) चलती है, तो आपको अपने आप से पूछना चाहिए कि क्या होगा अगर एक घंटे में DST परिवर्तन होता है; स्क्रिप्ट कुछ मामलों में दो बार नहीं चल सकी या नहीं चल सकी। के आधुनिक कार्यान्वयन cronकर रहे हैं काफी चालाक इस संबंध में, हालांकि।


5

आप उपयोग कर सकते हैं

date -d "30 days ago" +"%d/%m/%Y"

30 दिन पहले की तारीख प्राप्त करने के लिए, इसी तरह आप 30 को दिनों की x राशि से बदल सकते हैं


%Y%m%dप्रश्न का मिलान करने के लिए आपको अपना प्रारूप बदलना चाहिए । मैंने वैसे भी उत्थान किया क्योंकि यह ठीक से काम करता था।
इपिर

4

यहां एक समाधान जो सोलारिस और एआईएक्स के साथ भी काम करेगा।

कुछ घंटों के लिए घड़ी बदलने के लिए टाइमज़ोन में हेरफेर संभव है। दिन के समय की बचत के कारण, 24 घंटे पहले आज या कल से एक दिन पहले हो सकते हैं।

आपको यकीन है कि कल 20 या 30 घंटे पहले है। कौनसा? खैर, सबसे हाल ही में जो आज नहीं है।

echo -e "$(TZ=GMT+30 date +%Y-%m-%d)\n$(TZ=GMT+20 date +%Y-%m-%d)" | grep -v $(date +%Y-%m-%d) | tail -1

इको कमांड में उपयोग किया जाने वाला पैरामीटर बैश के साथ आवश्यक है, लेकिन ksh के साथ काम नहीं करेगा। Ksh में आप एक ही कमांड का उपयोग कर सकते हैं -e फ्लैग के बिना।

जब आपकी स्क्रिप्ट का उपयोग विभिन्न वातावरणों में किया जाएगा, तो आप स्क्रिप्ट को #! / Bin / ksh या #! / Bin / bash से शुरू कर सकते हैं। आप एक नई पंक्ति द्वारा \ n को भी बदल सकते हैं:

echo "$(TZ=GMT+30 date +%Y-%m-%d)
$(TZ=GMT+20 date +%Y-%m-%d)" | grep -v $(date +%Y-%m-%d) | tail -1

0

बस उपयोग dateऔर भरोसेमंद सेकंड:

जैसा कि आप ठीक से इंगित करते हैं, अंतर्निहित गणना के बारे में बहुत सारे विवरण छिपे हुए हैं यदि आप अंग्रेजी समय अंकगणित पर भरोसा करते हैं। जैसे -d yesterday, और -d 1 day agoअलग व्यवहार होगा।

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

date -d @$(( $(date +"%s") - 24*3600)) +"%Y-%m-%d"

यह एक और जवाब में बताया गया था । यह फ़ॉर्म विभिन्न dateकमांड लाइन के झंडे वाले प्लेटफार्मों में अधिक पोर्टेबल है , भाषा-स्वतंत्र है (उदाहरण के लिए "फ्रेंच लोकेल में" बनाम "" "पदानुक्रम"), और स्पष्ट रूप से (लंबी अवधि में) याद रखना आसान होगा, क्योंकि अच्छी तरह से, आप यह पहले से ही पता है। आप अन्यथा खुद पूछ रख सकते हैं: "यह था -d 2 hours agoया -d 2 hour agoफिर?" या "क्या यह -d yesterdayया -d 1 day agoजो मुझे चाहिए?")। यहाँ केवल मुश्किल सा है @

बैश के साथ सशस्त्र और कुछ नहीं:

बैश पर पूरी तरह से बैश, आप प्रिंटफ बिलिन के माध्यम से कल का समय भी प्राप्त कर सकते हैं:

 %(datefmt)T
     causes printf to output the date-time string resulting from using
     datefmt as a format string for strftime(3).  The  corresponding  argu
     ment  is an integer representing the number of seconds since the
     epoch.  Two special argument values may be used: -1 represents the
     current time, and -2 represents the time the shell was invoked.
     If no argument is specified, conversion behaves as if -1 had
     been  given.
     This is an exception to the usual printf behavior.

इसलिए,

# inner printf gets you the current unix time in seconds
# outer printf spits it out according to the format
printf "%(%Y-%m-%d)T\n" $(( $(printf "%(%s)T" -1) - 24*3600 ))

या, समान रूप से एक अस्थायी चर (बाहरी सब-वैकल्पिक वैकल्पिक, लेकिन पर्यावरण चर को साफ रखता है)।

(
  now=$(printf "%(%s)T" -1);
  printf "%(%Y-%m-%d)T\n" $((now - 24*3600));
)

नोट: मैनपेज के यह कहने के बावजूद कि %()Tफॉर्मेट करने वाले के लिए कोई भी तर्क डिफ़ॉल्ट नहीं होगा -1, मुझे लगता है कि इसके बजाय 0 मिलेगा (धन्यवाद, bash मैनुअल संस्करण 4.3.48)


0
date -d "yesterday" '+%Y-%m-%d'

इसे बाद में उपयोग करने के लिए:

date=$(date -d "yesterday" '+%Y-%m-%d')

2
हालांकि यह कोड ओपी की समस्या को हल कर सकता है, लेकिन यह स्पष्टीकरण देना बेहतर है कि आपका कोड ओपी के मुद्दे को कैसे संबोधित करता है। इस तरह, भविष्य के आगंतुक आपके पोस्ट से सीख सकते हैं, और इसे अपने स्वयं के कोड पर लागू कर सकते हैं। SO एक कोडिंग सेवा नहीं है, बल्कि ज्ञान के लिए एक संसाधन है। उच्च गुणवत्ता, पूर्ण उत्तर इस विचार को पुष्ट करते हैं, और इसके उत्थान की संभावना अधिक होती है। ये विशेषताएं, साथ ही आवश्यकता है कि सभी पोस्ट स्व-निहित हों, एसओ की कुछ ताकतें एक मंच के रूप में हैं जो हमें मंचों से अलग करती हैं। आप अतिरिक्त जानकारी जोड़ने और / या स्रोत प्रलेखन के साथ अपने स्पष्टीकरण के पूरक के लिए संपादित कर सकते हैं।
शेरलहोमन

0

आप उपयोग कर सकते हैं:

date -d "yesterday 13:55" '+%Y-%m-%d'

या जो भी समय आप पुनः प्राप्त करना चाहते हैं वह बैश द्वारा पुनः प्राप्त किया जाएगा।

महीने के लिए:

date -d "30 days ago" '+%Y-%m-%d'

0

जैसा कि यह सवाल टैग है "डीएसटी सुरक्षित"

और फोर्क टू dateकमांड इम्पी देरी का उपयोग करते हुए, शुद्ध बैश बिल्ट-इन का उपयोग करके एक सरल और अधिक कुशल तरीका है:

printf -v tznow '%(%z %s)T' -1
TZ=${tznow% *} printf -v yesterday '%(%Y-%m-%d)T' $(( ${tznow#* } - 86400 ))
echo $yesterday

यह कांटा करने की तुलना में अधिक प्रणाली के अनुकूल होने पर बहुत तेज है date

से V> = 5.0 , एक नया चर है$EPOCHSECONDS

printf -v tz '%(%z)T' -1
TZ=$tz printf -v yesterday '%(%Y-%m-%d)T' $(( EPOCHSECONDS - 86400 ))
echo $yesterday
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.