12小时至24小时时间转换器


27

令人惊讶的是,这个简单的任务似乎还不存在,所以...

您的任务是编写一个程序,该程序将12小时时间作为输入,并将其转换为“军事时间”或24小时时间格式。

输入将采用以下形式:

HH:MM am/pm

尽管可以有一些细微的变化:

  • 上午/下午与其余时间之间的间隔是可选的。

  • 最后一部分可以是“ am” /“ pm”或“ a” /“ p”。

  • 任何大写字母都可以。

输出将是输入的时间,转换为24小时格式。它可以是数字或字符串。

对于输入和输出:

  • 首先的0是可选的。最后3个位必须为0。

  • 分隔小时和分钟的定界符可以是“:”,“”(空格)或什么都不是。

其他说明:

  • 午夜可以表示为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's

是否允许在输入和输出中包含秒?
17Me21年

Answers:


8

V21 17字节

感谢@DJMcMayhem 4个字节!

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

在线尝试! 这需要的格式HH:MMx,其中x要么ap格式,并将其返回HH:MM

十六进制转储:

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字节

感谢Luis Mendo,节省了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

PowerShell23 20 19字节

date "$args"-f HHmm

在线尝试!

(如果您使用的是Windows,则可以省略get-,以减少到19个字节。在TIO上,它显然需要全Get-Date名。)

将输入作为字符串$args[0],将其用作Get-Datecmdlet 的输入,该cmdlet将其解析为.NET datetime对象。传递了-format参数HHmm以将其转换为军事时间(首都HH指定24小时制)。输出是隐式的。

解析引擎非常健壮,因此也允许添加类似12am或的输入12:00am。试一下TIO上的输入,看看还有什么用。

感谢@admalledd保存了3个字节...感谢@briantist保存了另一个字节


如果能够删除之间的空间$args[0]-f,以及删除周围格式STR单引号: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 am”。初始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
为什么要下票?
泰特斯(Titus),

我只是在推测,但这也许是因为您使用了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字节)

从shell脚本中:

输入中不接受空格

此时,最好使用$ 1并忽略其他args。

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)的输出的子字符串是49字节长3字节:

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字节感谢Kevin Cruijssen


与Java一样,Bout尽可能短,其中20%的代码是包限定符。
Magic Octopus Urn'1

规则说明为“ 对于输入和输出:-首位0是可选的。最后3位0是必需的。 ”,这意味着您可以更改HHmmHmm
凯文·克鲁伊森

@KevinCruijssen不错!

2

Japt,14个字节

Ð"1/"+U s sG21

在线尝试!

这仅适用于Chrome。这是适用于所有浏览器的版本:

Ð"1/"³+U s sG21

再次感谢ETHproductions的帮助!


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。不错的第一答案。您可以使用交换机,但是它们在你的BYTECOUNT数(如解释在这里)。在您的情况下,-p如果将单引号更改为双引号,则将为+1字节(因为仅需要)。
达达

谢谢。找不到该常见问题,想知道Stack Exchange团队是否可以将其固定在答案页面或其他内容上?
BRPocock

好吧,自从第4辑开始我就一直在Perling上,这让很头疼,您应该功劳并以那个为己任。☺
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位计算机上玩代码高尔夫真的很有趣,因为它显示了当今程序员甚至无需考虑即可完成的工作。
Shaun Bebbers

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。滥用main函数具有字符串数组的事实,将输入分为三部分:小时,分钟和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 2017年

是的,但是看起来并不好。
idrougge

鉴于这是一个挑战代码的挑战,如果您可以选择一个输出较长的程序,输出漂亮,或者选择一个较短的程序,输出丑陋,则选择后者。没有人会判断你。
Carcigenicate

2

C(clang),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:00pc?:)
亚伯汤姆

1
这将对时空连续性造成不可挽回的伤害。
Johan du Toit


2

C,87 72字节

@Johan du Toit节省了15个字节

调用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);
ceilingcat '18 -10-11


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,159152字节

#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

JavaScript,67个字节

f=s=>!~s.indexOf`pm`?s.slice(0,5):((+s.slice(0,2)+12)+s.slice(2,5))

输入类似于示例


对于不工作12:00 am12:00 pm
赫尔曼大号

1

Haskell,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)要么是“一”或“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

通用Lisp(151122字节)

好的,CL并不意味着“简洁”,但我只是感到惊讶,它并不是最冗长的。

这是122字节的版本,需要固定位置输入。0145pm145p可接受(在第一个字符位置的前导空格)。

(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)))

打印:

(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),文字:,两位数分钟以及可选的尾随ampm(仅小写)的形式输入。允许在时间周围和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,而仅使用ap代替amor pm,例如0134a上午01:34。在连续军事时间使用0000作为午夜输出。(如果允许将例如12:30 am转换为,我可以节省一些字节2430,但是我怀疑是否可以接受)。

在线尝试!

说明

最初的两个案例处理的是“ 12”小时,因为am / pm反转了12:

^12(.*)a
00$1

如果时间在午夜(12 am)到1 am之间,请将其更改为00而不是12,然后删除a

^(12.*)p
$1

如果时间在中午(12 pm)到1 pm之间,则删除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

将输入作为三个参数。假设第二个参数在必要时前导零,第三个参数是ap。通过将第三个参数作为间接变量名称来工作,因此将其加到小时数上;分钟数不受影响,因此仅直接输出。如果可以混合使用其他格式,则可以删除最后一个空格以保存一个字节。

(很烦人的是,当我最初加载该问题时,该问题并未出现在问题页面上,并且我偶然发现了该问题,因为我正在寻找另一个问题。)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.