Форматировать микросекунды как часы: минуты: секунды и т. Д.

28

Следующее вдохновлено вопросом, который возник сегодня на Stack Overflow .

Учитывая количество микросекунд 0 <= n <= 86400000000(например 12345678900), выведите отформатированную строку hh:mm:ss:000:000, например 03:25:45:678:900.

          0 -> '00:00:00:000:000'
12345678900 -> '03:25:45:678:900'
86400000000 -> '24:00:00:000:000'

У меня есть решение в Python в 209 байтов, но может ли оно пойти ниже?

Сэм
источник
1
Теперь я понимаю, что на самом деле это не стандартный формат записи времени, и hh:mm:ss.000000, вероятно, он был бы лучше (и проще). Тем не менее, не могу изменить это сейчас.
Сэм
1
Из любопытства, что это был за пост?
Цифровая Травма
@DigitalTrauma stackoverflow.com/questions/31251377 относительно новым пользователем. Правильный ответ уже был выбран, я просто играл в IDLE и придумал гротескно-понятное понимание словаря, которое не было особенно хорошим ответом на вопрос. Кто-то видел это и указал на этот сайт в комментарии. Я пришел сюда, написал вопрос (немного отличающийся от поста SO), а также написал значительно улучшенную версию моего ответа (который я не опубликовал, и который теперь избыточен для всех гораздо более компактных и оригинальных ответов ниже) ,
Сэм
Есть ли ограничение на количество часов на входе?
FUZxxl
Да, произвольно я сделал это <= 86400000000 мкс, поэтому <= 24 часа.
Сэм

Ответы:

15

Python 2, 82 79 байт

n=input()
o=""
for k in[1000]*2+[60]*3:o=":%0*d"%(k%7/2,n%k)+o;n/=k
print o[1:]

Создает строку, повторяя серию divmods. Единственный причудливый бит это тот %7/2, который отображает 1000 -> 3и 60 -> 2.

Sp3000
источник
6

Pyth, 31 байт

j\:_m>l`td+"00"%~/QddCM"ϨϨ<<<

Попробуйте онлайн: демонстрация

Объяснение:

                                 implicit: Q = input number
                       "ϨϨ<<<   string "ϨϨ<<<" (5 chars but 7 bytes)
                     CM          convert each to number => [1000, 1000, 60, 60, 60]
    m                            map each number d to:
                 /Qd                divide Q by d
                ~                   and update Q with the new value
               %~ Q d               but use the old value to calculate Q mod d
          +"00"                     add the result to the string "00"
     >                              but only take the last 
      l`td                          len(str(d-1)) chars
   _                             revert order
j\:                              join the strings with ":"s
Jakube
источник
5

Баш + кореутилс, 61

Самый короткий "основной" язык до сих пор ...

a=%02d:
printf $a$a$a%03d:%03d `dc -e$1\ A00~rA00~r60~r60~rf`

Тестовый вывод:

$ for t in 0 12345678900 86400000000; do ./usec.sh $t; echo; done
00:00:00:000:000
03:25:45:678:900
24:00:00:000:000
$ 
Цифровая травма
источник
4

C 97 байтов

q=1000,s=60;
#define f(n)printf("%02d:%02d:%02d:%03d:%03d",n/s/s/q/q,n/s/q/q%s,n/q/q%s,n/q%q,n%q)

Тестовый код:

int main(int intc, char **argv)
{
    long long n = atoll(argv[1]);
    f(n);
}
какой-то пользователь
источник
1
Ответы на C должны быть законченными, программами; не фрагмент
NobodyNada - Восстановить Монику
Это не упоминается в вопросе. Есть ли какие-то глобальные требования?
какой-то пользователь
Лазейки, которые по умолчанию запрещены
NobodyNada - Восстановите Монику
Нет. Если вы читаете ответ, он просто использует C в качестве примера. Правило применимо к каждому языку. Кроме того, ответ горячо оспаривается - см. Комментарий с самым высоким рейтингом. Суть в том, что Вопрос должен четко указывать, если требуется полная программа.
некий пользователь
3
Многие ответы на этом сайте используют функции вместо полных программ - например, я не думаю, что когда-либо видел ответ Java, который был бы законченной программой ...
Джерри Иеремия,
4

q (34)

Я уверен, что это может быть короче

":"sv 0 8 11__[;8]15$2_($)16h$1e3*

например

q)f:":"sv 0 8 11__[;8]15$2_($)16h$1e3*
q)f 12345678900
"03:25:45:678:900"
skeevey
источник
4
какие-нибудь онлайн-компиляторы? другими словами - как мне управлять этим как ленивым человеком?
Оптимизатор
32-битная версия доступна бесплатно на kx.com
Skeevey
хорошее место к сожалению, исправление добавляет несколько персонажей
Skeevey
1
Вы можете сократить больше байтов здесь":"sv 0 8 11__[;8]15$2_($)"n"$1e3*
WooiKent Lee
3

Юлия, 110 96 95 байт

t->(o="";for i=int([36e8,6e7,1e6,1e3,1]) x,t=t÷i,t%i;o*=lpad(x,i>1e3?2:3,0)*":"end;o[1:end-1])

Это создает безымянную функцию, которая принимает целое число в качестве входных данных и возвращает строку. Чтобы назвать его, дайте ему имя, например f=t->....

Ungolfed + объяснение:

function f(t)
    # Initialize an output string
    o = ""

    # Loop over an array consisting of the number of microseconds in
    # an hour, minute, second, millisecond, and microsecond
    for i = int([36e8, 6e7, 1e6, 1e3, 1])

        # Get the quotient and remainder for microseconds into t,
        # setting t to be the remainder
        x, t = t ÷ i, t % i

        # Left-pad x with zeroes and append it to the output
        o *= lpad(x, i > 1e3 ? 2 : 3, 0) * ":"
    end

    # o has a trailing :, so return everything but the last character
    o[1:end-1]
end

Примеры:

julia> f(12345678900)
"03:25:45:678:900"

julia> f(0)
"00:00:00:000:000"

julia> f(86400000000)
"24:00:00:000:000"
Алекс А.
источник
Хороший. Вы получили мой голос, потому что вдохновили меня на ответ Matlab :-)
Hoki
3

C #, 179 175 байт

Если у вас есть встроенные функции, почему бы не использовать их?

static void Main(string[]a){var t=TimeSpan.FromTicks(long.Parse(Console.ReadLine())*10);Console.Write(t.ToString((t.Days<1?"hh":@"\2\4")+@"\:mm\:ss\:ffffff").Insert(12,":"));}

С лучшим форматированием:

static void Main(string[]a){
    var t = TimeSpan.FromTicks(long.Parse(Console.ReadLine())*10);
    Console.Write(t.ToString((t.Days<1?"hh":@"\2\4")+@"\:mm\:ss\:ffffff").Insert(12,":"));
    Console.Read();
}
Када
источник
3

Excel, 65 63 символа

Предполагая, что ваши микросекунды находятся в A1 :

=TEXT(A1/50/1200^3,"[HH]:mm:ss:")&RIGHT(TEXT(A1,"000\:000"),7)

Выход:

        A              B
1            0  00:00:00:000:000
2  12345678900  03:25:46:678:900
3  86400000000  24:00:00:000:000
Hand-E-Food
источник
2

Perl, 141 78 байт

printf"%02d"x3.%03d:%03d",$_/36e8,$_/6e7%60,$_/1e6%60,$_/1e3%1e3,$_‌​%1e3

77 байт кода, +1 за -nфлаг. Бежать с:

echo 12345678900 | perl -ne'printf"%02d"x3.%03d:%03d",$_/36e8,$_/6e7%60,$_/1e6%60,$_/1e3%1e3,$_‌​%1e3'

Спасибо Томасу Ква и chilemagic за сокращение моего размера кода почти вдвое.

ASCIIThenANSI
источник
Я думаю, что 3600000000может быть 36e8.
lirtosiast
Вместо этого chomp($n=<STDIN>);вы можете запустить его как однострочник с -nфлагом (который считается за 1 символ). Вам также не нужно int(..)вокруг каждого $_. Используя наконечник Томаса, мы можем получить его, echo 12345678900 | perl -ne'printf"%02d:%02d:%02d:%03d:%03d\n",$_/36e8,$_/6e7%60,$_/1e6%60,$_/1e3%1e3,$_%1e3'и может быть даже более короткий путь!
hmatt1
Вам также не нужна \nвходная строка. Вы также можете заменить строку на"%02d:"x3 ."%03d:%03d"
hmatt1
@chilemagic Считает ли использование "echo" увеличение байтов?
ASCIIThenANSI
@ASCIIThenANSI это не так, потому что это не часть вашей программы. Символы, которые вы посчитаете, это те, которые находятся в одинарных кавычках, то есть printf"%02d:%02d:%02d:%03d:%03d\n",$_/36e8,$_/6e7%60,$_/1e6%60,$_/1e3%1e3,$_‌​%1e3вы добавляете дополнительный байт для -nфлага. Если вы используете, -nleнапример, это будет считаться дополнительным 2 (для nи l). Вы получаете -и e(или, Eесли вам нужно использовать say) бесплатно.
hmatt1
1

Matlab - 88 89 байт

Получил один байт с решением без использования встроенной функции:

n=[36e8,6e7,1e6,1e3];f=@(t)sprintf('%02d:%02d:%02d:%03d:%03d',fix([t mod(t,n)]./[n 1]))

Создайте встроенную функцию, которая принимает числовой входной аргумент tи возвращает строку.

он использует векторизованную комбинацию fixи modдля разделения элементов времени, а затем отображает.

это немного расстраивает, что форматирование выходной строки занимает так много, больше, чем сами вычисления ...

Тест:

for t=[0 12345678900 86400000000]
    f(t)
end

ans =
00:00:00:000:000
ans =
03:25:45:678:900
ans =
24:00:00:000:000

Версия 89 байтов:

f=@(t)sprintf('%s:%03d:%03d',datestr(fix(t/1e6)/86400,13),fix(mod(t,1e6)/1e3),mod(t,1e3))

Он делит число, использует встроенную функцию для части чч: мм: сс, которая не может обрабатывать микросекунды, поэтому строка завершается с помощью комбинации fixи modопераций

Hoki
источник
1

JavaScript (ES6), 128 118 116 111 байт

Возможно, в этом есть некоторый потенциал для игры в гольф.

f=t=>(t<864e8?new Date(t/1e3).toJSON().slice(11,-1):`24:00:00:000`).replace(`.`,`:`)+':'+('00'+t%1e3).slice(-3)

демонстрация

Это ES6, так что только Firefox, пока что:

f=t=>(t<864e8?new Date(t/1e3).toJSON().slice(11,-1):`24:00:00:000`).replace(`.`,`:`)+':'+('00'+t%1e3).slice(-3)

// DEMO
document.body.innerHTML += '<br>' + f(0);
document.body.innerHTML += '<br>' + f(12345678020);
document.body.innerHTML += '<br>' + f(86400000000);

rink.attendant.6
источник
Первая проверка не нужна, так как вопрос явно: 0 <= n <= 86400000000
edc65
@ edc65 Без первой проверки я могу получить только диапазон 0 ≤ n <86400000000, так как 8.64e10 перенесется на следующий день.
rink.attendant.6
Ах да, я пропустил это. toJSON () вместо toISOString ()?
edc65
1

C 113 103 105 байт

РЕДАКТИРОВАТЬ: вытолкнул еще несколько байтов

ИСПРАВЛЕНИЕ: удален длинный тип, спасибо некоторым пользователям

Не самый короткий ответ C, но я повеселился с возвратом кареты, поэтому мне показалось, что кому-то это может понравиться.

i,k,p=16;
#define f(n)for(;i<5;p-=i++<2?4:3)k=i<2?1000:60,printf("%0*d%c\r",p,n%k,i?58:13),n/=k;puts("");

Назовите это как:

int main() {
    long long n = 12345678900;
    f(n);

    return 0;
}
Андреа Биондо
источник
Зависит от платформы, «long» может быть просто 32-битным. (см. en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models ). Я избежал проблемы, объявив "f" как макрос вместо функции.
некий пользователь
Я заметил, что. Я взял GCC на x64, исправляя это завтра.
Андреа Биондо
0

CoffeeScript, 127 байт

Взял подход в ответе ASCIIThenANSI . Очень жаль, что в API консоли JavaScript нет форматных заполнителей для заполнения чисел.

p=(a,b)->('00'+~~a).slice -b||-2
f=(t)->console.log '%s:%s:%s:%s:%s',p(t/36e8),p(t/6e7%60),p(t/1e6%60),p(t/1e3%1e3,3),p t%1e3,3
rink.attendant.6
источник
0

Powershell, 153

$t=[timespan]::FromTicks(($a=$args[0]));"{0:D2}:{1:D2}:{2:D2}:{3:D3}:{4:000}"-f
[int]($t.TotalHours),$t.Minutes,$t.Seconds,$t.Milliseconds,(($a%1e4)/10)

использование

powershell -nologo .\modprintsec.ps1 123456789000    
03:25:45:678:900   
powershell -nologo .\modprintsec.ps1 864000000000   
24:00:00:000:000   
powershell -nologo .\modprintsec.ps1 0   
00:00:00:000:000 
blabb
источник
0

F #, 111 92 102 байта

Первая итерация: базовая идея.

Вторая итерация: меньшие константы

Третья итерация: правильное форматирование для однозначных частей.

Обратите внимание, что для работы этой функции должен быть указан int64.

let s,t=60L,1000L
let f n=sprintf"%02d:%02d:%02d:%03d:%03d"(n/s/s/t/t)(n/s/t/t%s)(n/t/t%s)(n/t%t)(n%t)

Пример выходов:

f 0L           -> "00:00:00:000:000"
f 12345678900L -> "03:25:45:678:900"
f 86400000000L -> "24:00:00:000:000"
Hand-E-Food
источник
0

PHP - 115 102 байта

Решение в 155 байтов (для удобства чтения обернуто здесь в 3 строки):

$a=$argv[1];
$h=($a-($m=($a=($a-($s=($a=($a-($t=($a=($a-($u=$a%1000))/1000)%1000))/1000)%60))/60)%60))/60;
printf("%02d:%02d:%02d:%03d:%03d",$h,$m,$s,$t,$u);

Вторая строка вычисляет (изнутри наружу) точные значения компонентов, начиная с микросекунд.

Более короткая версия (115 байт, для удобства чтения обернута в две строки):

$u=$argv[1];$h=($m=($s=($t=$u/1000)/1000)/60)/60;
printf("%02d:%02d:%02d:%03d:%03d",$h,$m%60,$s%60,$t%1000,$u%1000);

Он также использует встроенные назначения для вычисления числа входных микросекунд в миллисекундах, секундах, минутах и ​​часах с использованием чисел с плавающей запятой. Оператор модуля ( %) и формат десятичного числа ( %d) printf()затем используются, чтобы заставить их целые числа (дробная часть игнорируется).

Другое решение, которое использует функции даты (102 байта)

$u=$argv[1];
echo gmdate("H:i:s",strtotime("@".substr($u,0,-6))),":",substr($u,-6,3),":",substr($u,-3);

Часть часы: минуты: секунды обрабатывается функциями даты PHP, gmdate()а strtotime()миллисекунды и микросекунды извлекаются как строки из входного значения.

Использование:

$ php -r '$u=$argv[1];echo gmdate("H:i:s",strtotime("@".substr($u,0,-6))),":",substr($u,-6,3),":",substr($u,-3);' 7198898787; echo
01:59:58:898:787
axiac
источник
0

Java, 215 байт

String f(long n){return p(n/3600000000l,2)+":"+p(n/60000000%60,2)+":"+p(n/1000000%60,2)+":"+p(n/1000%1000,3)+":"+p(n%1000,3);}String p(long n,int i){String s=String.valueOf(n);while(s.length()<i){s="0"+s;}return s;}

Метод fвыполняет некоторые вычисления nдля определения часов, минут и т. Д. И делегирует его методу pдля правильного форматирования каждого значения.

отформатирован:

String f(long n) {
    return p(n / 3600000000l, 2) + ":" + p(n / 60000000 % 60, 2) + ":" 
            + p(n / 1000000 % 60, 2) + ":" + p(n / 1000 % 1000, 3) + ":" + p(n % 1000, 3);
}

String p(long n, int i) {
    String s = String.valueOf(n);
    while (s.length() < i) {
        s = "0" + s;
    }
    return s;
}

Использование:

public void demo() {
    long n = 12345678900l;
    System.out.println(f(n));
}
RCB
источник
-1

Рубин - 82 байта

puts (t=Time.at(0,gets.to_i)).strftime("%2H:%2M:%2S:%3L:#{(t.usec%1000).to_s.rjust(3,?0)}")
Xenotoad
источник
2
Но я насчитал 91 байт. Он также работает только в часовом поясе UTC.
jimmy23013