12 часов в 24 часа


27

Удивительно, но эта простая задача, кажется, еще не существует, так что ...

Ваша задача - написать программу, которая использует в качестве входных данных 12-часовое время и преобразует его в «военное время» или 24-часовой формат времени.

Вход будет в форме:

HH:MM am/pm

Хотя допускаются небольшие вариации:

  • Пробел, отделяющий am / pm от остального времени, не является обязательным.

  • Последняя часть может быть "am" / "pm" или "a" / "p".

  • Любая капитализация в порядке.

На выходе будет введено время, преобразованное в 24-часовой формат. Это может быть число или строка.

Для ввода и вывода:

  • 0 в первую очередь необязательны. 0 в последних 3 местах являются обязательными.

  • разделитель между часами и минутами может быть «:», «» (пробел) или ничего.

Другие заметки:

  • Полночь может быть выражена как 0000 или 2400.

  • Полночь будет считаться «утра», а полдень будет считаться «вечера».

Ваша программа может быть функцией или полной программой и должна либо возвращать результат, либо выводить его на стандартный вывод. Конечный пробел в порядке.

Примеры (вы не обязаны поддерживать каждый формат):

12:00am -> 0000
1200 pm -> 1200
1234Am  -> 00:34
134a    -> 134
01:34PM -> 13 34
1234pm  -> 1234  

Это код гольф, поэтому выигрывает наименьшее количество байтов. Поскольку это так тривиально, чтобы решить с помощью встроенного, было бы неплохо увидеть некоторый код, который решает это вручную (но использование встроенных модулей хорошо).

Просто чтобы уточнить, вы не обязаны поддерживать все возможные форматы. Хорошо поддерживать только один вход и один выходной формат (на ваш выбор). Однако я хотел бы ограничить формат, как описано выше (который уже довольно бесплатный). {1134,'pm'}, например, было бы неприемлемо.


Какие форматы мы должны поддерживать? Только один?
redstarcoder

@redstarcoder Да. Любой формат, который соответствует приведенным выше требованиям, подходит, но, как отмечено выше в примерах, вам не требуется поддерживать каждый формат. Единственный формат ввода и единый формат вывода - это хорошо.
Carcigenicate

разрешено ли нашим форматам требовать начальных нулей? Например, 01:54pmбудет работать, но 1:54pmне будет?
FlipTack

Да. Вы можете выбрать необходимый формат ввода.
Carcigenicate

Разрешено ли нам включать секунды в наш ввод и вывод?
12Me21

Ответы:


8

V , 21 17 байт

Спасибо @DJMcMayhem за 4 байта!

í12:/0:
çp/12
$x

Попробуйте онлайн! Это берет формат HH:MMxгде xлибо aили p, и возвращает его в форматеHH:MM

HexDump:

00000000: ed31 323a 2f30 3a0a e770 2f31 3201 2478  .12:/0:..p/12.$x
00000010: 0ae7 612f 2478                           ..a/$x

Объяснение:

í12:/0:   | find and replace 12: with 0: (to avoid replacing HH:12)
ç         | on every line
 p/       | that contains a p
   12^A   | increment 12 times (the first number, hours)
$x        | delete the character at the end of the line

Вход всегда будет в [1-12]порядке? В этом случае, я думаю, вы могли бы сделать ó^12/0вместоcw^R=^R"%12
DJMcMayhem

1
Кроме того, вы можете использовать «глобальную команду», чтобы применить команду к строкам, соответствующим регулярному выражению, которое короче, чем разрыв макроса. çp/12^Aчто эквивалентно :g/p/norm 12<C-a>в vim
DJMcMayhem

Я принял это, потому что это был самый низкий балл, который дал понять, что он не использует встроенный (хотя я не запрещал использовать их). Если у кого-то есть проблемы с этим выбором, я могу изменить свой ответ на справедливый. Я думаю, что этот ответ является самым заслуживающим, хотя.
Carcigenicate


10

Октава, 21 17 байт

Сохранено 4 байта благодаря Луису Мендо. Я мог бы указать формат № 15 вместо 'HHMM'.

@(c)datestr(c,15)

Объяснение:

Это анонимная функция принимает строку в cкачестве входных данных в формате: '11:34 AM'. datestrавтоматически распознает формат как один из стандартных форматов даты и выводит его в указанном формате с номером 15, то есть HH:MM.

Поскольку указанный формат вывода не имеет AMили PMOctave автоматически преобразует его в то, что вы называете военным временем.

Попробуйте онлайн.


Версия, не datestrиспользующая 35 байт

@(c)[c(1:4)+[1,2,0,0]*(c(5)>97),'']

Объяснение:

Принимает входную строку cв формате 1134am.

@(c)                              % Anonymous function
[c(1:4)                           % First 4 elements of the string
       +[1,2,0,0]                 % Add 1 and 2 to the first to the ASCII-value of the 
                                    first two characters
                 *)c(5)>97)       % if the fifth element is larger than 97 
                                    (the ASCII code for `a`).
                            ,'']  % Implicitly convert to string

Или другой подход для 37 байтов:

@(c)[c(1:4)+('1200'-48)*(c(5)>97),'']

7

PowerShell , 23 20 19 байт

date "$args"-f HHmm

Попробуйте онлайн!

(Если вы работаете в Windows, вы можете опустить get-, чтобы уменьшить до 19 байт. В TIO, очевидно, требуется полное Get-Dateимя.)

Принимает входные данные в виде строки $args[0], использует их в качестве входных данных для Get-Dateкомандлета, который анализирует его в datetimeобъект .NET . Это прошло с-f параметром ormat, HHmmчтобы преобразовать его в военное время (прописная HHуказывает 24-часовое время). Вывод неявный.

Механизм разбора довольно надежный, поэтому дополнительные входы, такие как 12am или 12:00amразрешены. Поиграйте с входом на TIO и посмотрите, что еще работает.

( Сохранено 3 байта благодаря @admalledd ... сохранено еще один байт благодаря @briantist )


Должно быть в состоянии удалить пространство между $args[0]и -f, а также удалить одинарные кавычки ул формата: date $args[0]-f HHmm. По крайней мере, это работает на моем
PowerShell

@admalledd За громкий крик, я всегда забываю эти цитаты. Серьезно, я думаю, что каждый раз, когда я использовал Get-Dateс -fкем-то, кто-то напоминал мне, что вам не нужны цитаты. И хороший вызов с удалением пробела тоже, так как синтаксический анализатор рассматривает ]как конец токена. Благодарность!
AdmBorkBork

5

Python 2, 44 байта

lambda s:`int(s[:2])%12+12*("p"in s)`+s[3:5]

Формат ввода:, 01:23amнеобязательный mи пробелы после минут
Формат вывода:123


5

Pyth, 21 20 байт

Aczd++*12}\pH%sG12PH

Принимает ввод формы 01 23aкак «01:23 утра». Начальный 0 не является обязательным.
Вывод имеет вид 123, с начальным 0 опущен.

В псевдокоде:

                         z = input()
A                        G, H =
 czd                         z.split(" ")       # splits into the form ["1","23p"]
                         (
     +*12}\pH            12*('p' in H) +        # add 12 if 'p' is in the string
             %sG12         int(G) % 12
    +             PH     ) + H[:-1]             # prepend hour to minutes, with a/p removed

Попробуйте онлайн!


4

PHP, 35 32 байта

Формат ввода: без учета регистра, требует двоеточия и m, формат вывода hhmm. использует встроенные модули:

<?=date(Hi,strtotime($argv[1]));

принимает входные данные из первого аргумента командной строки.

PHP, 45 байт, без встроенных модулей

формат ввода (h)h:mm a(m)строчные, формат вывода (h)hmm.

<?=($s=$argv[1])%12+12*($s[6]>a).$s[3].$s[4];

4
Почему отрицательный голос?
Тит

Я просто размышляю, но, возможно, это потому, что вы использовали PHP, а downvoter не любит PHP? : p
bash0r

3

JavaScript (ES6), 40 байт

a=>(new Date('1/1/1/'+a)+a).slice(16,21)

Ввод должен быть отформатирован так: 12:32 am


3

GNU Coreutils ( 18 16 байт)

Из сценария оболочки:

Не принимает пробелы во входных данных

В этот момент можно также использовать $ 1 и игнорировать дополнительные аргументы.

date -d$1 +%H%M

⇒ echo 'date -d$1 +%H%M' > time24
⇒ sh time24 1:45pm
1345
⇒ sh time24 1:45 pm
0145 # Wrong answer, “pm” ignored because of space

оригинал

Чтобы разрешить пробелы в вводе,

date -d"$@" +%H%M

3

C #, 46 байт

s=>System.DateTime.Parse(s).ToString("HH:mm");

Строки принимаются во входных данных, как 12:00 AM

Выполнение того же действия, но подстановка выходных данных из вызова по умолчанию ToString(при условии использования культуры en-GB), на 3 байта длиннее для 49 байтов:

s=>(System.DateTime.Parse(s)+"").Substring(11,5);

3

date, 0 + 8 = 8 байт

На предмет использования правильного инструмента для работы…

Принимает ввод в качестве аргумента командной строки. Выполнить с +%H%M -d(штраф 8 байт). Здесь нет настоящей программы; вся работа выполняется аргументами командной строки. (Это довольно хорошая демонстрация почему существует штраф за аргументы командной строки!)

Пример:

$ date +%H%M -d "12:05 am"
0005

3

Java 7, 138 106 105 104 байта

String a(String a){return new java.text.SimpleDateFormat("Hmm").format(new java.util.Date("Ja1,0,"+a));}

Попробуйте онлайн!

Входные данные разделены двоеточием и имеют пробел между временем и часами / часами. Выходные данные не разделены двоеточием.

-1 байт благодаря Кевину Круйссену


Как бы коротко это ни было для Java, 20% кода являются классификаторами пакетов.
Волшебная Урна Осьминога

Правила гласят: « Для ввода и вывода: - 0 в первую очередь являются необязательными. 0 в последних 3 местах являются обязательными. », Что означает, что вы можете изменить HHmmна Hmm.
Кевин Круйссен

@KevinCruijssen хороший улов!
Poke


2

Perl, 45 28 37 байт

28 37 байт

(з / о @ Дада)

(36 байт кода, 1 байт для -pпереключения компилятора )

Принимает 0145pmформаты типа, с am / pm или a / p. Требуются начальные нули на входах.

s/(..)(.)$//;$_=$_%12+12*(p eq$2).$1

Тест:

⇒ echo 0145pm | perl -p time24
1345
⇒ echo 0245pm | perl -p time24
1445
⇒ echo 1245pm | perl -p time24
1245
⇒ echo 1245am | perl -p time24
045

Мой оригинальный ответ

(также аккуратно пересмотрено)

(39-байтовый код, 1 байт для -pпереключения компилятора .)

Принимает только форму, такую ​​как 0145p или 0145a, и никакую другую, и требует perl -pрежима для работы.

s/(..)(..)([ap])/$1%12+12*($3eq"p").$2/e

тест:

⇒ echo 0145p | perl -p time24
1345
⇒ echo 1222a | perl -p time24
022
⇒ echo 1234p | perl -p time24
1234

Добро пожаловать на PPCG. Хороший первый ответ. Вы можете использовать переключатели, но они учитываются в вашем счетчике (как описано здесь ). В вашем случае это будет +1 байт (потому что -pтребуется только ), если вы измените одинарные кавычки для двойных кавычек.
Дада

Спасибо. Не нашли этот FAQ, интересно, может ли команда Stack Exchange прикрепить его на странице ответов или что-то в этом роде?
BRPocock

Хорошо, я был Перлингом с 4 серии, и это заставляет мою голову болеть, вы должны взять кредит и опубликовать себя с этим. ☺
BRPocock

Я думаю, что должно охватить это сейчас?
BRPocock

Я сделал ошибку, это решение не будет работать, когда минуты находятся в диапазоне от 0 до 9. Этот код работает тогда: s/(..)(.)$//;$_=$_%12+12*(p eq$2).$1 (37 байт). И, между прочим, ваше первое решение может быть немного проигнорировано: s/(..)(..)([ap])/$1%12+12*($3eq"p").$2/e(40 байт)
Dada

2

Commodore 64 BASIC, 301 байт перед запуском, 321 байт используется после запуска

0 A$="12:34AM":A=VAL(LEFT$(A$,2)+MID$(A$,4,2)):ON-(RIGHT$(A$,2)="AM")+1GOSUB1,2:TI$=A$:PRINTTI$:END
1 ON-(A=>1200ANDA<=1259)GOTO3:A=A+1200:GOTO3
2 ON-(A=>1200ANDA<=1259)GOTO4:ON-(A<=959)GOTO7:RETURN
3 A$=RIGHT$(STR$(A)+"00",6):RETURN
4 A=A-1200:IFA=0THENA$="000000":RETURN
5 IFA<10THENA$="000"+RIGHT$(STR$(A),1)+"00":RETURN
6 A$="00"+RIGHT$(STR$(A),2)+"00":RETURN
7 A$="0"+RIGHT$(STR$(A),3)+"00":RETURN

Для того, чтобы ввести это на реальном Commodore 64, вам нужно будет использовать сокращенные ключевые слова BASIC, такие как LE [shift] F для LEFT$, M [shift] I для и MID$т. Д ... или вы можете попробовать CBM PRG STUDIO.

TI$Переменной в Commodore BASIC представляет время в 24 - часовом формате , как HHMMSS при печати. Удаление пробела после номера строки не экономит память, так как Commodore BASIC все равно автоматически добавляет пробел, когда вы перечисляете программу после ее ввода.

При преобразовании числа в строку с помощью STR$Commodore BASIC добавит пробел (поэтому, если вы PRINT Aувидите пробел до того, как число будет показано), я удалил пробел в преобразовании числа в строку с помощью RIGHT$команды. Вы можете сохранить несколько байтов, изменив нулевую строку до:

0 A=VAL(LEFT$(A$,2)+MID$(A$,4,2)):ON-(RIGHT$(A$,2)="AM")+1GOSUB1,2:TI$=A$:PRINTTI$:END

поэтому перед запуском программы вам нужно будет указать время конвертации:

A$="01:22AM":GOTO 0

В любой момент после этого вы можете увидеть текущее время с помощью:

? TI$

Игра в гольф кода на 8-битных машинах действительно интересна, поскольку она показывает, сколько сделано для современного программиста, даже не задумываясь об этом.
Шон Бебберс

2

Java, 171 байт

enum t{;public static void main(String[] a){a=a[0].split("[: ]");System.out.format("%02d%02d",(Long.parseLong(a[0])+(a[2].charAt(0)=='p'?12:0))%24,Long.parseLong(a[1]));}}

Формат ввода HH:MM a/p и выходной формат HHMM. Злоупотребление тем фактом, что основная функция имеет массив строк для разделения ввода на 3 секции: часы, минуты и индикатор a / p.

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

Input: 01:02 a
Output: 0102

Input: 01:02 p
Output: 13:02

Input: 12:22 p
Output: 0022

Безголовая версия:

enum t {
    ;

    public static void main(String[] a) {
        a = a[0].split("[: ]");
        System.out.format("%02d%02d", (Long.parseLong(a[0]) + (a[2].charAt(0) == 'p' ? 12 : 0)) % 24, Long.parseLong(a[1]));
    }
}

Я не видел, enumчтобы держать main. Приятно :)
Роберт Бенсон

Вы можете опустить пробел в сигнатуре метода main: public static void main (String [] a) {...
staticmethod

2

REXX, 33 байта

arg h':'m a
say h+((a=pm)*12)':'m

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

12:34 pm -> 24:34
1:34 pm -> 13:34
1:34 am -> 1:34
0:34 AM -> 0:34

Это может быть сокращено на несколько байтов, если двоеточие в качестве разделителя не используется.


Разделитель двоеточия является необязательным.
Carcigenicate

Да, но это не выглядит хорошо.
idrougge

Учитывая, что это сложная задача для кода, если у вас есть возможность выбрать более длинную программу с красивым выводом или более короткую программу с более уродливым выводом, выберите последнее. Никто не будет судить тебя.
Carcigenicate

2

C (лязг) , 94 байта

h,m;f(){char a,b;scanf("%d:%d%c%c",&h,&m,&a,&b);printf("%02d%02d",a=='a'?(h%12):(12+h%12),m);}

Попробуйте онлайн!

Я здесь, чтобы учиться, поэтому любые советы о том, как я могу оптимизировать код, приветствуются.

@ Johan du Toit Спасибо за сохранение нескольких байтов!


Вам не нужно проверять b == 'm', и вы можете сделать его намного короче, используя встроенные операторы if:printf("%02d:%02d", (a=='p' ? 12 : 0) + (h %12), m);
Johan du Toit

1
@JohanduToit Что я ввожу в 6:00? :)
Абель Том

1
Это нанесет непоправимый вред пространственно-временному континууму.
Йохан дю Туа


2

C, 87 72 байта

Сохранено 15 байтов благодаря @Johan du Toit

Вызов f()с изменяемой строкой в ​​качестве аргумента, входные данные являются выходными.

Формат: HH:MMa/pгде a/pнижний aили нижний регистрp . Пробел между временем и спецификатором меридиана не допускается.

i;f(char*p){i=atoi(p)%12+(p[5]^97?12:0);*p=i/10+48;p[1]=i%10+48;p[5]=0;}

Попробуйте это на Ideone .


Вы можете сохранить пару байтов, используя следующее:i;f(char*p){i=atoi(p)%12+(p[5]^97?12:0);*p=i/10+48;p[1]=i%10+48;p[5]=0;}
Johan du Toit

Предложить (p[5]!=97)*12;вместо(p[5]^97?12:0);
floorcat

2

tcl, 45 47

Теперь с помощью встроенного:

puts [clock f [clock sc $s -f %I:%M%p] -f %R]

Тестируется на http://rextester.com/TSRXI8802, где есть скрипт, который запускает его с 01:00 до 1259.


2

SmileBASIC, 67 байт

INPUT T$P=POP(T$)>"a
TMREAD"00:"+T$OUT,H,M?H MOD 12+12*P,T$[3];T$[4]

Входные данные: HH:MMa/p

Выход: HH MM


1

R, 68 байт

x=substr(strptime(scan(,""),"%I:%M %p"),12,16);`if`(x=="","00:00",x)

Читает ввод из stdin, и предполагается, что он имеет один из следующих форматов:

  • 12:00 AM
  • 12:00 am
  • 12:00AM
  • 12:00am

и вывод в формате: [1] "00:00"

В большинстве случаев strptime()вывод в формате: "2017-01-06 12:00:00 CET"где дата является локальной датой. Как таковой, мы должны использовать substr()его только для возврата времени, однако, если ввод - полночь (например, 12:00amвыход - только то, "2017-01-06 CET"что является причиной для ifвещи в конце (должен быть какой-то более умный обходной путь).


Я действительно хотел найти более короткий путь lubridate, но название пакета слишком длинное (среди других проблем).
BLT

1

C 159 152 байта

#define C c[0]
main(i,c)char**c;{scanf("%s",C);i=atoi(C);if(C[5]-97){i+=i-12?12:0;sprintf(C,"%d",i);}else if(i==12)C[0]=C[1]=48;C[2]=58;C[5]=0;puts(C);}

Формат ввода: 07:30am



1

Mathematica, 33 байта

#~DateString~{"Hour24","Minute"}&

Анонимная функция. Принимает строку в качестве ввода и возвращает строку в качестве вывода. Работает с большинством форматов, в том числе hh:mm AM/PM.



1

Хаскель, 61 персонаж

Укороченная версия:

c[a,b,c,d,e]=(mod(read[a,b]::Int)12+f e,[c,d])
f 'a'=0
f _=12

Формат ввода: HHMM(a/p)где(a/p) 'a' или 'p' без круглых скобок.

Выходной формат: (hs, MM) - кортеж, содержащий часы в виде целого числа и MM в виде строки.

Пример:

> c "1200p"
(12,"00")
> c "1200a"
(0,"00")

Более длинная версия (с более полезными именами и одной заменой hs):

conv [h0,h1,m0,m1,ap] = (mod hs 12 + offset ap, [m0,m1])
    where hs = read [h0,h1] :: Int

offset 'a'=  0
offset  _ = 12

1

Common Lisp ( 151 122 байт)

Хорошо, CL не должен быть «кратким», но я просто удивлен, что он не самый многословный для этого.

Вот 122-байтовая версия, которая требует ввода в фиксированной позиции. 0145pmили 145pявляются приемлемыми (с пробелом в первой позиции символа).

(defun a(x)(let((h(parse-integer(subseq x 0 2)))(m(subseq x 2 4)))(format nil "~a~a" (+(mod h 12)(if(find #\p x)12 0))m)))

PPRINT:

(DEFUN A (X)
  (LET ((H (PARSE-INTEGER (SUBSEQ X 0 2)))
        (M (SUBSEQ X 2 4)))
    (FORMAT NIL
            "~a~a"
            (+ (MOD H 12) (IF (FIND #\p X) 12 0))
            M)))

Лучше, но больше

Используя только Common-Lispпакет. Принимает (только) ввод в виде целочисленных часов (с или без начального 0), литерала :, двухзначных минут и дополнительного трейлинга amили pm(только в нижнем регистре). Разрешает пробелы во времени и вокруг AM / PM, но не сразу после :.

(defun a(x)(let*((c(position #\: x))(h(parse-integer(subseq x 0 c)))(m(subseq x(1+ c)(+ 3 c))))(format nil "~a~a" (+(mod h 12)(if(find #\p x)12 0))m)))

Тест:

GOLF> (a "  1:45 am ")
"1:45"
GOLF> (a "  1:45 pm ")
"13:45"
GOLF> (a " 12:45 am ")
"0:45"
GOLF> (a "12:45p")
"12:45"

pprint определение функции:

(DEFUN A (X)
  (LET* ((C (POSITION #\: X))
         (H (PARSE-INTEGER (SUBSEQ X 0 C)))
         (M (SUBSEQ X (1+ C) (+ 3 C))))
    (FORMAT NIL "~a~a"
            (+ (MOD H 12)
               (IF (FIND #\p X)
                   12
                   0))
            M)))

Де-затемненный:

(defun 12->24-hour (timestring) 
  "Given a  TIMESTRING with  hours:minutes and a  trailing “am”  or “pm”
   \(lowercase-only), return the 24-hour time without a delimiter as
   a  string \(eg,  \"1:45am\" →  \"0145\"). Spaces  surrounding the
   time or  meridian markers are ignored  \(eg, \" 02:22 pm  \") but
   other junk in the string may cause incorrect behavior."
  (let ((colon (position #\: timestring)))
    (let ((hours (parse-integer (subseq timestring 0 colon)))
          (minutes (subseq timestring (+ 1 colon) (+ 3 colon))))
      (format nil "~a~a"
              (+ (mod hours 12) (if (find #\p timestring) 12 0))
              minutes))))

1

Сетчатка , 61 60 байт

^12(.*)a
00$1
^(12.*)p
$1
a

(\d\d)(.*)p
$1$*x12$*x$2
x+
$.&

Входные данные даны без разделительного двоеточия, обязательного начала 0и использования только aили pвместо amили pm, например 0134a, 01:34. Выводит по прямому военному времени, используя 0000 как полночь. (Я мог бы сохранить несколько байтов, если мне разрешено конвертировать, например, в 12:30 в2430 , но я сомневаюсь, что это приемлемо).

Попробуйте онлайн!

объяснение

Первые два случая имеют дело с «12» часами, так как am / pm меняется на 12:

^12(.*)a
00$1

Если время между полуночью (12:00) и 1:00, измените ее на 00 вместо 12 и удалите a.

^(12.*)p
$1

Если время между 12:00 и 13:00, уберите p, чтобы просто получить 24-часовое время.

За любой другой час:

a
 

Если время утра, просто удалите, aчтобы получить 24 часа.

(\d\d)(.*)p
$1$*x12$*x$2
x+
$.&

Если время вечера, удалите p. Преобразовать компонент часа в унарный, добавить 12 и преобразовать обратно в десятичную. Оставьте минуты без изменений.


1

Пакет, 40 байт

@set/aa=0,p=12,h=%1%%12+%3
@echo %h% %2

Принимает ввод как три аргумента. Предполагается, что второй аргумент имеет ведущий ноль в случае необходимости, третий аргумент либо либо, aлибо p. Работает, обрабатывая третий аргумент как имя косвенной переменной, добавляя его к числу часов; количество минут не изменяется, поэтому выводится напрямую. Если смешивание разных форматов в порядке, то последний пробел может быть удален для сохранения байта.

(Скорее досадно, этот вопрос не появлялся на странице вопросов, когда я первоначально загружал его, и я наткнулся на него только потому, что искал другой вопрос.)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.