2011-08-21 13 views
5

मैं गणितीय तरीके से और किसी भी फ़ंक्शन का उपयोग किए बिना और सरल गणित सूत्र में यूनिक्स-टाइमस्टैम्प से दिन संख्या की गणना कैसे कर सकता हूं।गणित के तरीके में एक यूनिक्स-टाइमस्टैम्प से दिन संख्या की गणना करें?

1313905026 -> 8 (आज 2011/08/21)

उत्तर

3

यह करने के लिए कोई सरल सूत्र है। युग के बाद से आपको वर्षों की संख्या (लीप वर्षों के लिए लेखांकन) घटाना होगा, जिसके लिए शायद किसी लूप या किसी प्रकार की अलग गणना की आवश्यकता होगी। फिर चालू वर्ष के लिए प्रत्येक माह में सेकंड की संख्या घटाने के लिए कुछ प्रकार के लूप का उपयोग करें। जो आपको छोड़ दिया गया है वह वर्तमान में महीने में सेकंड की संख्या है।

मैं ऐसा कुछ करूंगा।

x = ...//the number of seconds 
year = 1970 

while (x > /*one year*/){ 
x = x - /*seconds in january, and march-december*/ 
if(year % 4 == 0){ 
    x -= /*leapeay seconds in february*/ 
}else{ 
    x -= /*regular seconds in february*/ 
} 
} 

//Then something like this: 

if(x > /*seconds in january*/){ 
x -= /*seconds in january*/ 
} 
if(x > /*seconds in february*/){ 
x -= /*seconds in january*/ 
} 

. 
. 
. 

//After that just get the number of days from x seconds and you're set. 

संपादित

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

पहले युग के बाद से सेकंड में वर्तमान समय होने दें।

चलो चार वर्षों में सेकेंड की संख्या हो। यह तीन नियमित वर्ष और एक लीप वर्ष है। यह होना चाहिए: 126230400.

अब यदि आप एफ द्वारा योगदान के सभी समय निकाल लेते हैं, तो आपको शेष मिलेगा: y।

तो y = n% एफ

कई मामलों अब कर रहे हैं: 1. y कम है कि एक वर्ष के 2. y दो साल से कम 3. y तीन साल और कम से कम है है दो महीने से 4. y तीन वर्ष से कम और अधिक से अधिक दो महीने से है 5. y, कम से कम चार साल

नोट जिसने 1972 था एक लीप वर्ष है, इसलिए यदि आप 1970, भी आप से चार से गिनती बाएं बंद दो साल में एक छलांग वर्ष होगा।

जेन, फेब, फेबली, मार, मई, ..., प्रत्येक महीने में सेकेंड की संख्या होनी चाहिए (आपको इसे गणना करने की आवश्यकता होगी)।

डी वर्तमान माह की दिन संख्या का प्रतिनिधित्व करता है और डी दिन (86400) में सेकंड की संख्या का प्रतिनिधित्व करता है। y नियमित वर्ष में सेकंड की संख्या का प्रतिनिधित्व करता है, और yly एक लीप वर्ष में सेकंड की संख्या का प्रतिनिधित्व करता है।

y = (t % F) 
if(y < Y){ 
if(y > jan){ 
    y -= jan 
} 
if(y > feb){ 
    y -= feb 
} 
. 
. 
. 
d = y % D 
} 
else if(y < 2 * y){ 
y = y - Y 
if(y > jan){ 
    y -= jan 
} 
if(y > feb){ 
    y -= feb 
} 
. 
. 
. 
d = y % D 
} 
else if(y < 2 * y + yLY){ 
y = y - 2 * Y 
if(y > jan){ 
    y -= jan 
} 
if(y > febLY){ 
    y -= febLY 
} 
. 
. 
. 
d = y % D 
} 
else{ 
y = y - 2 * Y - yLY 
if(y > jan){ 
    y -= jan 
} 
if(y > feb){ 
    y -= feb 
} 
. 
. 
. 
d = y % D 
} 

जांची नहीं। इसके अलावा, चूंकि पृथ्वी वास्तव में 1 रोटेशन/24 घंटों तक नहीं फैलती है, इसलिए उन्होंने कभी-कभी समय पर समायोजन किया है। आपको लगता है कि क्षेत्र में अनुसंधान कारक का एक सा सब करने की ज़रूरत

+0

धन्यवाद, तो मैं अपने बेहतर लगता है की गणना करने के यह DATE फ़ंक्शंस का उपयोग कर रहा है, क्योंकि मैं इसे एक एसक्यूएल क्वेरी के बीच में रखना चाहता हूं। –

+0

रुको, मुझे मिल गया! बस एक सेकंड पर लटकाओ और मैं ऊपर अपना जवाब पोस्ट करूंगा। लिंक के पीछे उत्तेजनात्मक स्पष्टीकरण के लिए – JSideris

2
t = unix time 
second = t MOD 60 
minute = INT(t/60) MOD 60 
hour = INT(t/60/60) MOD 24 
days = INT(t/60/60/24) 
years = INT(days/365.25) 
year = 1970 + years + 1 

1970 तो गुरूवार के साथ शुरू किया, हम सप्ताह के दिन की गणना कर सकते हैं:।

weekday = (days + 4) MOD 7 

तो रविवार 0. दिन है आप तो रविवार को दिन 1 होना चाहते हैं बस 1 जोड़ें।

अब, पता लगाएं कि हम साल में कितने दिन हैं।

days = days - years * 365 - leapdays 

अंत में, हमें महीने का महीना और दिन मिल जाता है।

IF year MOD 4 = 0 THEN ly = 1 ELSE ly = 0 
WHILE month <= 12 
    month = month + 1 
    IF month = 2 THEN 
     DaysInMonth = 28 + NOT(year MOD 4) + NOT(year MOD 100) 
      + NOT(year MOD 400) 
    ELSE 
     DaysInMonth = 30 + (month + (month < 7)) MOD 2 
    END IF 
    IF days > DaysInMonth THEN days = days - DaysInMonth 
END WHILE 

यह = TRUE = 1, FALSE 0, नहीं सही = 0, और नहीं असत्य की बूलियन मान मान लिया गया है, 1.

अब हम वर्ष, माह, महीने, घंटे के दिन है = मिनट, और दूसरा लीप वर्षों के लिए समायोजन के साथ गणना की।

3

unix timestamp में leap seconds शामिल नहीं है, इसलिए हमें इसके बारे में चिंता करने की ज़रूरत नहीं है।

#include <iostream> 

int 
main() 
{ 
    int s = 1313905026; 
    int z = s/86400 + 719468; 
    int era = (z >= 0 ? z : z - 146096)/146097; 
    unsigned doe = static_cast<unsigned>(z - era * 146097); 
    unsigned yoe = (doe - doe/1460 + doe/36524 - doe/146096)/365; 
    int y = static_cast<int>(yoe) + era * 400; 
    unsigned doy = doe - (365*yoe + yoe/4 - yoe/100); 
    unsigned mp = (5*doy + 2)/153; 
    unsigned d = doy - (153*mp+2)/5 + 1; 
    unsigned m = mp + (mp < 10 ? 3 : -9); 
    y += (m <= 2); 
    std::cout << m << '/' << d << '/' << y << '\n'; // 8/21/2011 
} 

यह आउटपुट:: यहाँ एक शाखा-कम , एक unix timestamp से y/मा/दि क्षेत्रों प्राप्त करने के लिए लूप-कम एल्गोरिथ्म है

8/21/2011 

आप रुचि नहीं रखते हैं के रूप में y और m में (केवल d में), आप उपरोक्त गणना से अंतिम पंक्तियों को खत्म कर सकते हैं।

यह एल्गोरिदम वर्णन here में विस्तार से वर्णन किया गया है। इस लिंक में एक पूर्ण व्युत्पन्न, और लाखों वर्षों तक फैले यूनिट परीक्षण शामिल हैं (जो ओवरकिल है)।


शाखा-कम: क्या एल्गोरिथ्म में छोटी शाखाओं ऊपर MacOS पर -O3 पर दूर बजना द्वारा अनुकूलित कर रहे हैं की तरह लग रहा:

__Z14get_day_numberi:     ## @_Z14get_day_numberi 
    .cfi_startproc 
## BB#0: 
    pushq %rbp 
Ltmp0: 
    .cfi_def_cfa_offset 16 
Ltmp1: 
    .cfi_offset %rbp, -16 
    movq %rsp, %rbp 
Ltmp2: 
    .cfi_def_cfa_register %rbp 
    movslq %edi, %rax 
    imulq $-1037155065, %rax, %rcx ## imm = 0xFFFFFFFFC22E4507 
    shrq $32, %rcx 
    addl %ecx, %eax 
    movl %eax, %ecx 
    shrl $31, %ecx 
    sarl $16, %eax 
    leal (%rax,%rcx), %edx 
    leal 719468(%rax,%rcx), %esi 
    testl %esi, %esi 
    leal 573372(%rax,%rcx), %eax 
    cmovnsl %esi, %eax 
    cltq 
    imulq $963315389, %rax, %rcx ## imm = 0x396B06BD 
    movq %rcx, %rsi 
    shrq $63, %rsi 
    shrq $32, %rcx 
    sarl $15, %ecx 
    addl %esi, %ecx 
    imull $146097, %ecx, %ecx  ## imm = 0x23AB1 
    movl %eax, %esi 
    subl %ecx, %esi 
    subl %eax, %esi 
    leal 719468(%rsi,%rdx), %eax 
    movl %eax, %ecx 
    shrl $2, %ecx 
    imulq $1506180313, %rcx, %rdx ## imm = 0x59C67CD9 
    shrq $39, %rdx 
    movl %eax, %esi 
    subl %edx, %esi 
    imulq $963321983, %rcx, %rcx ## imm = 0x396B207F 
    shrq $43, %rcx 
    addl %esi, %ecx 
    movl %eax, %edx 
    shrl $4, %edx 
    imulq $7525953, %rdx, %rdx ## imm = 0x72D641 
    shrq $36, %rdx 
    subl %edx, %ecx 
    imulq $1729753953, %rcx, %rsi ## imm = 0x6719F361 
    shrq $32, %rsi 
    movl %ecx, %r8d 
    subl %ecx, %eax 
    movl %ecx, %edi 
    movl $3855821599, %edx  ## imm = 0xE5D32B1F 
    imulq %rcx, %rdx 
    subl %esi, %ecx 
    shrl %ecx 
    addl %esi, %ecx 
    shrl $8, %ecx 
    imull $365, %ecx, %ecx  ## imm = 0x16D 
    subl %ecx, %r8d 
    shrl $2, %edi 
    imulq $1506180313, %rdi, %rcx ## imm = 0x59C67CD9 
    shrq $39, %rcx 
    shrq $47, %rdx 
    addl %r8d, %eax 
    subl %ecx, %eax 
    leal (%rax,%rdx), %ecx 
    leal 2(%rcx,%rcx,4), %esi 
    movl $3593175255, %edi  ## imm = 0xD62B80D7 
    imulq %rsi, %rdi 
    shrq $39, %rdi 
    imull $153, %edi, %edi 
    subl %edi, %esi 
    leal 4(%rcx,%rcx,4), %ecx 
    subl %esi, %ecx 
    movl $3435973837, %esi  ## imm = 0xCCCCCCCD 
    imulq %rcx, %rsi 
    shrq $34, %rsi 
    leal 1(%rax,%rdx), %eax 
    subl %esi, %eax 
    popq %rbp 
    retq 
    .cfi_endproc 
+0

+1: http://howardhinnant.github.io/date_algorithms.html#civil_from_days – Semo

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

  • कोई संबंधित समस्या नहीं^_^