2012-07-13 16 views
8

मैं एक जावास्क्रिप्ट काउंटर बना रहा हूं जो 'सेकंड पहले' की गणना करता है। मेरे पास जेएस टाइम ऑब्जेक्ट में मेरा समय है, और मुझे स्टैक ओवरफ़्लो पर "टाइम फर्क" फ़ंक्शन स्निपेट मिला, लेकिन यह "2 घंटे पहले" प्रदर्शित करता है। मैं इसे "5 घंटे, 10 मिनट और 37 सेकंड पहले प्रदर्शित करने के लिए कैसे प्राप्त कर सकता हूं।"जावास्क्रिप्ट अस्पष्ट समय (जैसे '10 मिनट पहले') जो सटीक सेकंड में है

इस समारोह में "20 सेकंड पहले" वर्तमान समय और कुछ की टाइमस्टैम्प धर्मान्तरित एक गुप्त तारीख के बजाय:

यहाँ मैं के साथ काम कर रहा हूँ है

function timeDifference(current, previous) { 
    var msPerMinute = 60 * 1000; 
    var msPerHour = msPerMinute * 60; 
    var msPerDay = msPerHour * 24; 
    var msPerMonth = msPerDay * 30; 
    var msPerYear = msPerDay * 365; 

    var elapsed = current - previous; 

    if (elapsed < msPerMinute) { 
     return Math.round(elapsed/1000) + ' seconds ago'; 
    } else if (elapsed < msPerHour) { 
     return Math.round(elapsed/msPerMinute) + ' minutes ago'; 
    } else if (elapsed < msPerDay) { 
     return Math.round(elapsed/msPerHour) + ' hours ago'; 
    } else if (elapsed < msPerMonth) { 
     return 'approximately ' + Math.round(elapsed/msPerDay) + ' days ago'; 
    } else if (elapsed < msPerYear) { 
     return 'approximately ' + Math.round(elapsed/msPerMonth) + ' months ago'; 
    } else { 
     return 'approximately ' + Math.round(elapsed/msPerYear) + ' years ago'; 
    } 
} 

और यहाँ क्या मैं मैं प्रत्येक सेकंड के समय "गिनती" करने के लिए उपयोग कर रहा हूँ। मैं यह कहने के लिए "5 घंटे, 3 मिनट, 10 सेकंड पहले" और चाहते हैं तो 1 सेकंड बाद में, "5 घंटे, 3 मिनट, 11 सेकंड पहले"

var newTime = new Date(data.popular[i].timestamp*1000) 
var relTime = timeDifference(new Date(),newTime) 

setInterval(function(){ 
    var theTimeEl = $('.timestamp-large').filter(function(){ 
     return $(this).html() == relTime 
    }); 
    newTime.setSeconds(newTime.getSeconds() + 1); 
    var relTime = timeDifference(new Date(), newTime); 
    $(theTimeEl).html(relTime); 
    console.log(relTime) 
}, 1000) 

चर Newtime में समय आ गया है यूटीसी जावास्क्रिप्ट दिनांक प्रारूप। relTime है कि "सेकंड पहले" प्रारूप में। अंतराल टाइमस्टैम्प तत्वों के गुच्छा के माध्यम से loops और हर बार टिकट के लिए सही चुनता है। फिर यह उस समय एक सेकंड जोड़ता है, इसे वापस "अस्पष्ट समय" (सेकेंड पहले) में परिवर्तित करता है, एचटीएमएल को नए समय के साथ बदलता है और इसे कंसोल में लॉग करता है।

मैं "5 घंटे पहले" 5 घंटे, 37 मिनट, 10 सेकंड पहले "कैसे बदलूं? समय अंतर समारोह को संशोधित करने की आवश्यकता है।

+0

आप सेट इंटरवल के अंदर 'var relTime' को फिर से घोषित क्यों कर रहे हैं? – ErikE

+0

पीएस मैं सही एचटीएमएल आइटम खोजने के लिए एक बहुत ही अलग विधि का उपयोग करूंगा। एक डेटा होना चाहिए- [कुछ] टैग जिसे आप प्रत्येक में जोड़ सकते हैं जो सही HTML के साथ उचित टाइमस्टैम्प से संबंधित हो सकता है। – ErikE

+0

@ErikE मुझे फिर से रिटाइम घोषित करना है या फिर यह हमेशा प्रारंभिक मूल्य होगा। और .attr ('datasomething') का उपयोग कैसे कर रहा है .html() से बेहतर है? – alt

उत्तर

2

तर्क बदलें ताकि माप की एकमात्र सबसे बड़ी इकाई को खोजने के बजाय यह शेष के साथ कुछ कर सके।

मूल रूप से आपको जो करना होगा, वह सबसे बड़ी वृद्धि के साथ शुरू होता है, मूल्य ढूंढता है, फिर शेष को प्राप्त करने के लिए कुल से घटा देता है। फिर दोहराना।

ऐसा कुछ ऐसा हो सकता है, मैंने इसका परीक्षण नहीं किया है।

var elapsed = current - previous; 
var remainder = elapsed; 

int years; 
int months; 

years = Math.floor(remainder/msPerYear); 
remainder = remainder % msPerYear; 

months = Math.floor(remainder/msPerMonth); 
remainder = remainder % msPerMonth; 

// repeat 

फिर बस अपनी स्ट्रिंग को चर से बाहर बनाएं।

+0

आपको रहने वाले चर की आवश्यकता क्यों है? – alt

+0

@ जैक्सन, आपके उदाहरण का उपयोग करते हुए कहते हैं कि आपके पास 5 घंटे और 37 मिनट थे, आप मूल 'elapsed' मान पर गणित नहीं कर सकते हैं। अन्यथा आपको 5 घंटे, 337 मिनट (5 घंटे * 60 मिनट + 37 मिनट) मिलेंगे। तो आप 'elapsed' मान लेते हैं, घटाएं कि आप कितने पूर्ण घंटे प्राप्त कर पाए थे, और इसे' शेष 'में संग्रहीत करें ताकि आप शेष मिनटों को समझ सकें। – Brandon

0

इस चाल करना चाहिए:

var msPerMinute = 60 * 1000; 
var msPerHour = msPerMinute * 60; 
var msPerDay = msPerHour * 24; 
var msPerMonth = msPerDay * 30; 
var msPerYear = msPerDay * 365; 

function timeDifference(current, previous) { 

var remainder = current - previous; 
var message = ""; 
var sep = ""; 

var years = Math.floor(remainder/msPerYear); 
remainder = remainder - years * msPerYear; 
if (years > 0) { 
    message += years + " years"; 
    sep = ", "; 
    console.log(message); 
} 

var months = Math.floor(remainder/msPerMonth); 
remainder = remainder - months * msPerMonth; 
if (months > 0) { 
    message += sep + months + " months"; 
    sep = ", "; 
    console.log(message); 
} 

var days = Math.floor(remainder/msPerDay); 
remainder = remainder - days * msPerDay; 
if (days > 0) { 
    message += sep + days + " days"; 
    sep = ", "; 
    console.log(message); 
} 

var hours = Math.floor(remainder/msPerHour); 
remainder = remainder - hours * msPerHour; 
if (hours > 0) { 
    message += sep + hours + " hours"; 
    sep = ", "; 
    console.log(message); 
} 

var minutes = Math.floor(remainder/msPerMinute); 
remainder = remainder - minutes * msPerMinute; 
if (months > 0) { 
    message += sep + minutes + " minutes"; 
    sep = ", "; 
    console.log(message); 
} 

var seconds = Math.floor(remainder/1000); 
remainder = remainder - seconds * 1000; 
if (months > 0) { 
    message += sep + seconds + " seconds"; 
    sep = ", "; 
    console.log(message); 
} 

message += " ago"; 

var pos = message.lastIndexOf(','); 
message = message.substring(0,pos) + ' and' + message.substring(pos+1) 

return message; 
}; 

var output = timeDifference(new Date(2012, 10, 20, 12, 0, 59), new Date(2012, 2, 13, 10, 15, 12)); 
console.log(output); 

आउटपुट: 8 महीने, 12 दिन, 1 घंटे, 45 मिनट और 47 सेकंड पहले

इस कोर्स का एक सा कम दोहराव होने की पुनर्संशोधित किया जा सकता है । आप इस पहेली को इसके साथ काम करने का प्रयास कर सकते हैं: http://jsfiddle.net/vawEf/

+0

यदि मैं पीएसटी के साथ कुछ डालता हूं, तो यह सही ढंग से लौटाता है। मेरे पास पीडीटी है और यह "और 5 घंटे पहले" लौटाता है। किसी भी विचार hwo मुझे अपने टाइमस्टैम्प के साथ काम करने के लिए? वे इस तरह दिखते हैं: 'गुरु जुलाई 12 2012 16:57:41 जीएमटी -00000 (पीडीटी) ' – alt

6

यहां एक ऐसा फ़ंक्शन है जो आप पूछ रहे हैं उसके करीब है।

var timeparts = [ 
    {name: 'year', div: 31536000000, mod: 10000}, 
    {name: 'day', div: 86400000, mod: 365}, 
    {name: 'hour', div: 3600000, mod: 24}, 
    {name: 'minute', div: 60000, mod: 60}, 
    {name: 'second', div: 1000, mod: 60} 
]; 

function timeAgoNaive(comparisonDate) { 
    var 
     i = 0, 
     l = timeparts.length, 
     calc, 
     values = [], 
     interval = new Date().getTime() - comparisonDate.getTime(); 
    while (i < l) { 
     calc = Math.floor(interval/timeparts[i].div) % timeparts[i].mod; 
     if (calc) { 
     values.push(calc + ' ' + timeparts[i].name + (calc != 1 ? 's' : '')); 
     } 
     i += 1; 
    } 
    if (values.length === 0) { values.push('0 seconds'); } 
    return values.join(', ') + ' ago'; 
} 

console.log(timeAgoNaive(new Date(Date.parse('Jun 12 2006 11:52:33')))); 
console.log(timeAgoNaive(new Date(new Date().getTime() - 3600000))); 
console.log(timeAgoNaive(new Date())); 

परिणाम:

6 years, 33 days, 4 hours, 52 minutes, 22 seconds ago 
1 hour ago 
0 seconds ago 

मैं इसे "भोली" कहा जाता है क्योंकि यह वास्तव में मानव तरीका है कि हम समय की गणना पर ध्यान देना नहीं है। यदि यह "1/1/2013 12:01:00 बजे" है, तो वास्तव में, "1/1/2012 12:01:00 पूर्वाह्न" की तुलना में "1 वर्ष, 0 महीने, 0 दिन, 0 घंटे, 0 मिनट , 0 सेकंड पहले "। लेकिन यह आपके द्वारा प्रस्तुत किए गए फ़ंक्शन में तर्क को विस्तारित करके नहीं करेगा, और यह मेरे कार्य में ऐसा नहीं करेगा (साथ ही मेरा फ़ंक्शन महीनों का उपयोग नहीं करेगा)। 365 दिनों से अधिक वर्षों का बेहतर अनुमान 365.24 है, लेकिन इसे भी अनदेखा किया जाता है।

मैंने आपके द्वारा अनुरोध किए गए खाली समय के हिस्सों को बाहर रखा, न्यूनतम समय पर "0 सेकंड" छोड़कर जब कोई समय नहीं मिला।

अब, यदि आप उस मानव-तरह की गणना करने के तरीके चाहते हैं, तो आपको कुछ चीजों का फैसला करना होगा। आप सीमा पार नहीं कर सकते हैं क्योंकि 28 फरवरी से 1 मार्च पूरे महीने नहीं है। दूसरा, यहां एक प्रश्न वास्तविक समस्या का पर्दाफाश करेगा:

  • फरवरी 2 से 31 मार्च तक कितने महीने और दिन हैं?

यदि आप एक महीने के रूप में 2 फरवरी से 2 मार्च की गणना करते हैं, तो यह 1 महीने 2 9 दिन है। लेकिन क्या होगा यदि यह 2 जनवरी से 1 मार्च तक था? यही उनके बीच बीतने की संख्या है। क्या अब 1 महीने (अप्रैल के लिए) + मार्च में + 1 दिन + जनवरी में 31 दिन 1 महीने 32 दिनों के लिए है? क्या आप चाहते हैं कि आपके महीने भौतिक कैलेंडर के साथ मिलें ताकि मानव अपनी उंगली से ट्रैक कर सके और सही तिथि प्राप्त कर सके? यह आपके विचार से कहीं अधिक कठिन है।

यदि आप समझदार और पूर्ण नियमों के साथ जवाब दे सकते हैं कि आप "मानव-जैसी विलुप्त समय लगाना" कैसे करेंगे तो शायद मैं आपको ऐसा करने के लिए एक और कार्य लिख सकता हूं।

अद्यतन

यहाँ एक नया समारोह है कि महीनों करता है, और (एक महीने में ३०.४,३६,६६,६६६ दिन) एक वर्ष में 365.24 दिन होते हैं:

var timeparts = [ 
    {name: 'millenni', div: 31556736000, p: 'a', s: 'um'}, 
    {name: 'centur', div: 3155673600, p: 'ies', s: 'y'}, 
    {name: 'decade', div: 315567360}, 
    {name: 'year', div: 31556736}, 
    {name: 'month', div: 2629728}, 
    {name: 'day', div: 86400}, 
    {name: 'hour', div: 3600}, 
    {name: 'minute', div: 60}, 
    {name: 'second', div: 1} 
]; 

function timeAgoNaive2(comparisonDate) { 
    var i = 0, 
     parts = [], 
     interval = Math.floor((new Date().getTime() - comparisonDate.getTime())/1000); 
    for (; interval > 0; i += 1) { 
     value = Math.floor(interval/timeparts[i].div); 
     interval = interval - (value * timeparts[i].div); 
     if (value) { 
     parts.push(value + ' ' + timeparts[i].name + (value !== 1 ? timeparts[i].p || 's' : timeparts[i].s || '')); 
     } 
    } 
    if (parts.length === 0) { return 'now'; } 
    return parts.join(', ') + ' ago'; 
} 

console.log(timeAgoNaive2(new Date(Date.parse('Jun 12 2006 11:52:33')))); 
console.log(timeAgoNaive2(new Date(new Date().getTime() - 3600000))); 
console.log(timeAgoNaive2(new Date())); 
console.log(timeAgoNaive2(new Date(-92709631247000))); 

आउटपुट:

6 years, 1 month, 1 day, 10 hours, 53 minutes, 44 seconds ago 
1 hour ago 
now 
2 millennia, 9 centuries, 8 decades, 4 months, 26 days, 22 hours, 41 minutes, 47 seconds ago 

यह अभी भी बेवकूफ़ है, लेकिन यह थोड़ा बेहतर काम करता है। इसके अलावा यह बीसी जैसे वास्तविक पुरानी तिथियों के लिए काम करेगा। लोगों को। :)

+0

इसे सभी" 0 ____ पहले "छिपाना चाहिए। मुझे लगता है कि अन्यथा यह सही है। – alt

+0

@ जैक्सन गैरीटी अपडेटेड। क्या यह ठीक है कि इसमें महीनों शामिल नहीं हैं? मैं एक संस्करण पर काम कर रहा हूं जो करता है। – ErikE

+0

बहुत अच्छा! क्या यह 0 को छुपाता है? मुझसे यह कैसे होगा? – alt

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