2016-12-03 9 views
0

HintergrundKonvertieren von UTC in Dezimal Zeit

ich ein neues Datum/Zeit-System erstellt werden soll, basierend auf einer alte Französisch-Version mit einigen Modifikationen.

Dies beinhaltet neue Mengen UTC-Datum/Zeit Umwandlung:

  • 12 Monate => 10 Monate
  • 52 Wochen => 36,5 Wochen
  • 28/31 Tage pro Monat => 36/37 Tage pro Monat
  • 24Stunden => 20 Stunden
  • 60 Minuten => 100 Minuten
  • 60 Sekunden => 100 Sekunden

ich eine Uhr in JavaScript als Proof of Concept codiert haben, aber noch nicht sicher, ob ich richtig berechnet haben alles, zusätzlich, ob es der beste Ansatz ist:

-Code

1) getDecimalDate() berechnet den Tag des Jahres und berechnet dann den Monat, in dem er existiert, in einem neuen Kalender mit 36 ​​oder 37 Tagen pro Monat. Berechnet dann das neue Datum des Monats.

function getDecimalDate(date) { 
    var oldDay = 1000 * 60 * 60 * 24, 
     startYear = new Date(Date.UTC(date.getUTCFullYear(), 0, 0)), 
     day = Math.floor((date - startYear)/oldDay), 
     num = 0, 
     month = 1; 
    if (day > 36) { num += 36; month = 2; } 
    if (day > 73) { num += 37; month = 3; } 
    if (day > 109) { num += 36; month = 4; } 
    if (day > 146) { num += 37; month = 5; } 
    if (day > 182) { num += 36; month = 6; } 
    if (day > 219) { num += 37; month = 7; } 
    if (day > 255) { num += 36; month = 8; } 
    if (day > 292) { num += 37; month = 9; } 
    if (day > 328) { num += 36; month = 10; } 
    return { day: day - num, month: month, year: date.getUTCFullYear(), num: num }; 
} 

2) getDecimalTime() berechnet die Anzahl der Millisekunden seit Mitternacht, ändert es dann von den alten Millisekunden pro Tag, um neue Summen, dann Stunden berechnet, Minuten usw.

function getDecimalTime(date) { 
    var oldDay = 1000 * 60 * 60 * 24, 
     newDay = 1000 * 100 * 100 * 20, 
     startDay = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())), 
     delta = ((date - startDay)/oldDay) * newDay; 

    var hours = Math.floor(delta/10000000) % 20; 
    delta -= hours * 10000000; 
    var minutes = Math.floor(delta/100000) % 100; 
    delta -= minutes * 100000; 
    var seconds = Math.floor(delta/1000) % 100; 
    delta -= seconds * 1000; 
    var milliseconds = Math.floor(delta) % 1000; 
    return { milliseconds: milliseconds, seconds: seconds, minutes: minutes, hours: hours }; 
} 

Sie eine Arbeits sehen hier Version: https://jsfiddle.net/kmturley/7mrwc3x3/9/

Ergebnisse

Denken Sie daran, ich habe aus Tag/Monat Namen mit lateinischen (Nov = 9, sterben = Tag, Dezember = 10, Mense = Monat)

  • String - Samstag 3. Dezember => Novdie Decmense 10
  • Datum - 2016.03.12 => 10-10-2016
  • Time - 22.47.52 => 18:98:43

Fragen

  1. Ist die Mathematik korrekt?
  2. Gibt es Probleme mit Zeitzonen? Ich habe versucht, alle Date-Objekte in UTC konvertieren, aber JavaScript kann tricky
  3. Kann ich den Code verbessern? die Monatsauswahl scheint wie könnte verbessert werden, aber ich konnte nicht einen besseren Weg, 36 und 37 Tage Monate zu zählen. if (num% 36.5 === 1) würde nicht funktionieren?

Vielen Dank!

Update - 7. Dezember 2016 - neue Versionen basieren auf Lösung: https://jsfiddle.net/kmturley/7mrwc3x3/10/

https://github.com/kmturley/decimal-time

+0

'Gibt es irgendwelche Probleme mit Zeitzonen? Ich habe versucht, alle Date-Objekte in UTC zu konvertieren, aber JavaScript kann schwierig sein. Nun, eine Zeitzone ist nicht komplizierter als ein Offset, also würde ich persönlich das UTC-Bit dieser Funktionen behalten. – Keith

+0

Alle Datumsobjekte ** sind ** UTC. Der Zeitzonen-Offset stammt vom Host, die Nicht-UTC-Methoden verwenden diesen Offset, um "lokale" Werte zu berechnen. Wenn Sie alle UTC-Methoden verwenden, erhalten Sie UTC-Werte und der Zeitzonen-Offset wird nicht verwendet. – RobG

+0

Guter Punkt, ich habe etwas unnötigen Code, der UTC in UTC konvertiert :) –

Antwort

1

Ist die Mathematik richtig?

Sie hat nicht gesagt, welche 35 Tage Monaten haben und die 36 haben, so müssen wir, dass die richtigen wenn Aussagen sind annehmen. Sie zeigen nicht, wie Datum erstellt wird, so dass es möglicherweise nicht OK ist. Und Sie sagen nicht, was für Schaltjahre passiert, dieses System scheint nur 365 Tage im Jahr zu haben.

Die folgende:

  • 24 Stunden => 20 Stunden
  • 60 Minuten => 100 Minuten
  • 60 Sekunden => 100 Sekunden

nicht scheint richtig zu sein. Meinen Sie damit eigentlich:

  • 1 Tag = 20 Dezimalstunden
  • 1 Nachkommastelle Stunde = 100 Dezimalminuten
  • 1 Nachkommastelle Minute = 100 Dezimalsekunden
  • 1 Nachkommastelle Sekunde = 1000 dezimal Millisekunden

Ihre Strategie, die Zeit in ms und Skalierung auf Dezimal ms zu bekommen, scheint in Ordnung, ich werde nur die folgenden Kommentare machen.

In getDecimalTime es ist einfacher StartDay, indem man zuerst das KopierenDatum dann berechnen ihre UTC Stunden auf Null:

startDay = new Date(+date); 
startDate.setUTCHours(0,0,0,0); 

Dann Skala:

var diffMilliseconds = date - startDate; 
var decimalMilliseconds = diffMilliseconds/8.64e7 * 2.0e8; 

so 1 Standard Millisekunde = 2.314814814814815 Dezimal Millisekunden

In der Datumsfunktion, der Ausdruck:

new Date(date.getUTCFullYear(), 0, 0) 

wird das Vorjahr ein Datum für den 31. Dezember erstellen (d Datum 0), wenn Sie nach dem 1. Januar sind dann soll es sein:

new Date(date.getUTCFullYear(), 0, 1); 

So wahrscheinlich ist du ein Tag aus. Ansonsten scheint der Code korrekt zu sein.Für mich wäre die bekommen dezimal Zeitfunktion einfacher als:

function getDecimalTime(date) { 
 
    // Pad numbers < 10 
 
    function z(n){return (n<10?'0':'')+n;} 
 
    // Copy date so don't modify original 
 
    var dayStart = new Date(+date); 
 
    var diffMs = date - dayStart.setUTCHours(0,0,0,0); 
 
    
 
    // Scale to decimal milliseconds 
 
    var decMs = Math.round(diffMs/8.64e7 * 2.0e8); 
 
    
 
    // Get decimal hours, etc. 
 
    var decHr = decMs/1.0e7 | 0; 
 
    var decMin = decMs % 1.0e7/1.0e5 | 0; 
 
    var decSec = decMs % 1.0e5/1.0e3 | 0; 
 
    decMs  = decMs % 1.0e3; 
 
    return z(decHr) + ':' + z(decMin) + ':' + z(decSec) + '.' + ('0' + z(decMs)).slice(-3); 
 
} 
 

 
// Helper to format the time part of date 
 
// as UTC hh:mm:ss.sss 
 
function formatUTCTime(date) { 
 
    function z(n){return (n<10?'0':'')+n;} 
 
    return z(date.getUTCHours()) + ':' + 
 
     z(date.getUTCMinutes()) + ':' + 
 
     z(date.getUTCSeconds()) + '.' + 
 
     ('00' + date.getUTCMilliseconds()).slice(-3); 
 
} 
 

 
// Test 00:00:00.003 => 00:00:00.007 
 
// i.e. 3ms * 2.31decms => 6.93decms 
 
var d = new Date(Date.UTC(2016,0,1,0,0,0,3)); 
 
console.log(getDecimalTime(d)); 
 

 
// Test 12:00:00.000 => 10:00:00.000 
 
// i.e. noon to decimal noon 
 
var d = new Date(Date.UTC(2016,0,1,12,0,0,0)); 
 
console.log(getDecimalTime(d)); 
 

 
// Test current time 
 
d = new Date(); 
 
console.log(formatUTCTime(d)); 
 
console.log(getDecimalTime(d));

+0

wow erstaunlich, das ist genau das, was ich brauchte. Gehen Sie jetzt zum Testen und öffnen Sie es unter: https://github.com/kmturley/decimal-time Vielen Dank! –

+0

aktualisierte Geige mit Lösung: https://jsfiddle.net/kmturley/7mrwc3x3/10/ auch basierend auf Date.prototype, die es viel einfacher macht! –

Verwandte Themen