2016-12-03 5 views
0

фонПреобразование UTC в десятичное время

Я хочу, чтобы создать новую систему даты/время на основе старой французской версии с некоторыми изменениями.

Это включает в себя преобразование даты UTC/раз в новых количествах:

  • 12 месяцев => 10 месяцев
  • 52 недели => 36,5 недель
  • 28/31 дней в месяц => 36/37 дней в месяц
  • 24 часа => 20 часов
  • 60 минут => 100 минут
  • 60 секунд => 100 секунд

Я закодировал часы в JavaScript как доказательство концепции, но уверены в том, есть ли я правильно все рассчитали, это дополнительно ли это лучший подход:

Код

1) getDecimalDate() вычисляет день года, затем выдает, какой месяц он существует в новом календаре 36 или 37 дней в месяц. Затем вычисляет новую дату месяца.

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() вычисляет количество миллисекунд, прошедших с полуночи, а затем изменяет его от старых миллисекунд в день до новых сумм, затем вычисляет часы, минуты и т.д.

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 }; 
} 

Вы можете увидеть работу версия здесь: https://jsfiddle.net/kmturley/7mrwc3x3/9/

Результаты

Имейте в виду, что я сделал до/названия месяцев день латинскими (Nov = 9, умри = день, декабрь = 10, mense = месяц)

  • String - Суббота 3 декабря => Novdie Decmense 10
  • Дата - 03-12-2016 => 10-10-2016
  • Время - 22:47:52 => 18:98:43

Вопросы

  1. Is математика правильная?
  2. Есть ли проблемы с часовыми поясами? я пытался конвертировать все объекты Date в UTC, но JavaScript может быть сложно
  3. Могу ли я улучшить код? выбор месяца кажется может быть улучшен, но я не мог найти лучшего способа подсчета 36 и 37-дневных месяцев. if (num% 36.5 === 1) не будет работать?

Спасибо!

Update - 7 декабря 2016 - новые версии на основе решения: https://jsfiddle.net/kmturley/7mrwc3x3/10/

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

+0

'есть ли проблемы с часовыми поясами? Я попытался преобразовать все объекты Date в UTC, но JavaScript может быть сложным'. Ну, часовой пояс не более сложный, чем смещение, поэтому я лично буду хранить бит UTC этих функций. – Keith

+0

Все объекты даты ** являются ** UTC. Смещение часового пояса от хоста, методы, отличные от UTC, используют это смещение для вычисления «локальных» значений. Если вы используете все методы UTC, вы получите значения UTC, а смещение часового пояса не будет использовано. – RobG

+0

хороший момент, у меня есть ненужный код, конвертирующий UTC в UTC :) –

ответ

1

ли математика правильно?

Вы не сказали, какие месяцы имеют 35 дней и которые имеют 36 таким образом, мы должны признать, что если утверждение верно. Вы не показываете, как создается , чтобы оно могло быть или не быть ОК. И вы не говорите, что происходит в високосные годы, эта система, по-видимому, имеет только 365 дней в году.

Следующая:

  • 24 часа => 20 часов
  • 60 минут => 100 минут
  • 60 секунд => 100 секунд

не кажется правильным. Вы на самом деле имели в виду:

  • 1 день = 20 десятичных часы
  • 1 десятичного час = 100 десятичных минут
  • 1 десятичной минута = 100 десятичных секунды
  • 1 десятичной секунду = 1000 десятичной миллисекунда

Ваша стратегия получения времени в миллисекундах и масштабирования до десятичных ms кажется прекрасной, я просто сделаю следующие комментарии.

В getDecimalTime проще вычислить startDay первым копирования даты затем установив его в формате UTC часов до нуля:

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

Тогда шкала:

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

так 1 стандарт миллисекунда = 2,314814814814815 десятичные миллисекунды

В функции даты, выражение:

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

создаст дату 31 декабря предыдущего года (т.е. дата 0), если вы после 1 января, то это должно быть:

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

Скорее всего, у вас один день. В противном случае код кажется правильным.Для меня, получить десятичную функция времени будет проще, так как:

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 amazing, это именно то, что мне нужно. Собираемся протестировать сейчас и с открытым исходным кодом: https://github.com/kmturley/decimal-time Спасибо! –

+0

обновленная скрипка с решением: https://jsfiddle.net/kmturley/7mrwc3x3/10/ также на основе Date.prototype, что делает его намного проще! –