Java - 12 小时到 24 小时格式 (hackerrank)

Java - 12 H to 24 Hour Format (hackerrank)

注意: 我花了 2 天的时间尽可能多地查看它是否重复。如果我遗漏了什么,我深表歉意。这个问题是为了找出我尝试的解决方案的问题所在,而不是现有的解决方案之一。

我的问题

我试图在 Java 7 中解决一些关于 hackerrank 的问题,我遇到了时间转换问题,问题陈述是:

问题:"Given a time in -hour AM/PM format, convert it to military (24-hour) time."

示例输入 07:05:45PM

示例输出 19:05:45

我查看了涉及库(例如 java.text.SimpleDateFormat、Calendar 等)的解决方案,但我正在尝试在没有它们的情况下自行完成。我在这里面临的问题是我的解决方案在某些测试用例上失败但在其他测试用例上有效。简而言之,这不是正确的解决方案。我看到了其他解决方案,但我想知道为什么我的答案失败了。你能帮我告诉我哪里会失败以及我该如何纠正它吗?

我看过的一些解决方案是:

Conversion from 12 hours time to 24 hours time in java

我的代码在这里:

import java.io.*;
import java.math.*;
import java.text.*;
import java.util.*;
import java.util.regex.*;

public class Solution {

    static String timeConversion(String s) {

        //get the string into an array using : as a separator
        String[] time_array = s.split(":");

        //military_time variable to be returned
        String military_time = new String();

        //final HH part
        String hh_final = new String();
        //Rest after HH to be concatenated to get military_time
        String rest = new String();


        StringBuilder REST_mil_builder = new StringBuilder();
        for (int i = 2; i < 8; i++) {
            REST_mil_builder.append(s.charAt(i));
        }
        //"rest" basically gets everything after HH excluding AM/PM, so 01:03:40PM would have a "rest" value of ":03:40"
        rest = REST_mil_builder.toString();

        int hh = Integer.parseInt(time_array[0]);
        String AMPM_contains = time_array[2];

        //converting if the last piece after the split contains "PM"
        if (AMPM_contains.contains("PM")) {
            hh = hh + 12;
            hh = hh == 24 ? 0 : hh;
        }

        //converting hh to have a 0 before it because when it is an integer 01 will be just 1 which we don't want
        StringBuilder hh_build = new StringBuilder();
        if (hh >= 0 && hh <= 9) {
            hh_build.append("0");
            hh_build.append(hh);
            hh_final = hh_build.toString();
        } else {
            hh_build.append(hh);
            hh_final = hh_build.toString();
        }

        //military time concatenation
        military_time = hh_final + rest;
        //Midnight is 12:00:00AM on a 12-hour clock, and 00:00:00 on a 24-hour clock
        military_time = s == "12:00:00AM" ? "00:00:00" : military_time;
        //Noon is 12:00:00PM on a 12-hour clock, and 12:00:00 on a 24-hour clock.
        military_time = s == "12:00:00PM" ? "12:00:00" : military_time;

        return military_time;

    }

    private static final Scanner scan = new Scanner(System.in);

    public static void main(String[] args)  {

        //tried several 12 hour time formats here
        String result = timeConversion("01:30:59PM");
        System.out.println(result);
    }
}

请试试这个static String timeConversion(String s) function。希望对你有帮助。

static String timeConversion(String s) {

        String[] time = s.split(":");

        String hours = time[0];
        String minutes = time[1];
        String seconds = time[2].substring(0, 2);
        String dayEve = time[2].substring(2, 4);
        if (dayEve.equals("AM")) {
            return ((hours.equals("12") ? "00" : hours) + ":" + minutes + ":" + seconds);
        } else {
            return ((hours.equals("12") ? hours : (Integer.parseInt(hours) + 12)) + ":" + minutes + ":" + seconds);
        }

    }

基本逻辑是:-

如果 'AM' 和 hours == 12 则小时设置为 00 否则不要更改 hours.

如果 'PM' 和 hours == 12 则不要更改 hours 否则小时数设置为 hours = hours+12

请使用 SimpleDateFormat:

public static String to24Time(String str) throws ParseException {
    DateFormat df12 = new SimpleDateFormat("hh:mm:ssa", Locale.US);
    DateFormat df24 = new SimpleDateFormat("HH:mm:ss", Locale.US);
    return df24.format(df12.parse(str));
}

P.S. 这是来自 Hackerrank 的任务:Algorithms/Warmup/Time Conversion.

  1. 没有任何注释禁止使用java内部类进行时间解析,您必须手动进行。
  2. 提供的答案为该任务 100% 测试通过

P.P.S 如果您不想使用 SimpleDateTime,这是如何使用 正则表达式 的示例。请注意,我没有提供输入字符串的完整验证;在某些情况下(例如对于像 21:17:17PM 这样的非法 12h 时间格式)它 returns 非法结果而不是异常:

public static String to24Time(String str) throws ParseException {
    final Pattern TIME_12 = Pattern.compile("(?<hour>\d{2}):(?<minute>\d{2}):(?<second>\d{2})(?<part>am|pm)");
    Matcher matcher = TIME_12.matcher(str.toLowerCase());

    if (matcher.matches()) {
        int hour = Integer.parseInt(matcher.group("hour"));
        return ("pm".equals(matcher.group("part")) ? hour + 12 : hour) + ":" + matcher.group("minute") + ':' + matcher.group("second");
    }

    return null;
}
    System.out.println(timeConversion("12:30:59AM"));
    System.out.println(timeConversion("11:30:59AM"));
    System.out.println(timeConversion("12:30:59PM"));
    System.out.println(timeConversion("11:30:59PM"));

预期输出:

00:30:59
11:30:59
12:30:59
23:30:59

观察到的输出:

12:30:59 (wrong)
11:30:59 (correct)
00:30:59 (wrong)
23:30:59 (correct)

编辑: 简而言之,您的代码似乎没有考虑到 12 小时与 12 小时制不同。你可能会说它被用作00小时。我认为修复你的程序不会太难,所以我会让你有第一枪的乐趣。如果您需要提示,请在评论中跟进。我们都很乐意提供帮助。

顺便说一句,您在代码的三个地方使用了 new String()。我认为这是多余的,因为您永远不会将创建的空字符串用于任何事情。

您的代码失败是因为它没有正确处理第 12 小时,即 12:xx:xxAM 应该映射到 00:xx:xx,而 12:xx:xxPM 应该映射到 12:xx:xx,正如所指出的

与其尝试修复您拥有的过于复杂的代码,不如使用另一种方法,无需使用 SimpleDateFormat

将前 2 位数字解析为数字。如果数字是 12,将其设置为 0。一个技巧是使用模 12。如果输入以 PM 结尾,则添加 12。现在重建字符串,用新数字替换前 2 位数字,并删除AM/PM 后缀.

像这样:

public static String timeConversion(String s) {
    int hour = Integer.parseInt(s.substring(0, 2)) % 12;
    if (s.endsWith("PM"))
        hour += 12;
    return String.format("%02d", hour) + s.substring(2, 8);
}

使用 Ole 测试 V.V。

System.out.println(timeConversion("12:30:59AM"));
System.out.println(timeConversion("11:30:59AM"));
System.out.println(timeConversion("12:30:59PM"));
System.out.println(timeConversion("11:30:59PM"));

输出

00:30:59
11:30:59
12:30:59
23:30:59

以下是我使用 JavaScript 解决它的方法:

function timeConversion(s) {


    var res;

    var pos = s.substring(-2, 8);

    var split = pos.split(':');

    if (split[0] == 12 && s.endsWith('AM')) {
        res = '00' + ':' + split[1] + ':' + split[2];

    } else if (split[0] == 12 && s.endsWith('PM')) {
        res = '12' + ':' + split[1] + ':' + split[2];

    } else if (split[0] < 12 && s.endsWith('AM')) {
        res = split[0] + ':' + split[1] + ':' + split[2];

    } else if (split[0] < 12 && s.endsWith('PM')) {
        var add = Number(split[0]) + 12;
        res = add + ':' + split[1] + ':' + split[2];
    }
    return res;
}
static String timeConversion(String s) {
    int hrs = 12;
    String[] split = s.split(":");
    String originalAMPM = split[2].substring(2,4);
    String hours = split[0]; String minutes = split[1]; String seconds = split[2].substring(0,2);
    if(originalAMPM.equals("PM")) {
        if(!hours.equals("12"))
            hrs = Integer.parseInt(hours) + 12;
        return hrs + ":" + minutes + ":" + seconds;
    }
    else {
        if(hours.equals("12"))
            hours = "00";
        return hours + ":" + minutes + ":" + seconds;
    }
}
   

#!/bin/python3

import os
import sys
import re
#
# Complete the timeConversion function below.

def timeConversion(s):

    if s[len(s)-2:]=='PM':
        
        if s[0] == '0':
            s1=s.strip('0')
            sn = s1.strip('PM')
            return sn.replace(sn[0],str(int(sn[0])+12))

        elif s[0:2]=='12':
            
            return s.strip('PM')
        else:
            sn = s.strip('PM')
            return sn.replace(sn[0:2],str(int(sn[0:2])+12)) 

    else: #s[len(s)-2:]=='AM':

        if s[0:2]=='12':
            s1=s.strip('AM')
            return s1.replace(s[0:2],'00')
        else:
            return s.strip('AM') 
                     
        

    
if __name__ == '__main__':
    f = open(os.environ['OUTPUT_PATH'], 'w')

    s = input()

    result = timeConversion(s)

    f.write(result + '\n')

    f.close()

以下是我使用 JavaScript 解决它的方法:

function timeConversion(s) {
    let time = [];
    let mid = s.slice(0,2);
    if(s.includes('PM')){        
        if( mid === '12' ){
            time = s;
        } else{
          let mid1 = Number(mid)+12;
          time = s.replace(mid, mid1.toString());   
        }             
    } else if(mid === '12'){ 
       time = s.replace(mid, '00');        
    } else time = s;    
   return time.slice(0,-2);
};
SimpleDateFormat df = new SimpleDateFormat("hh:mm:ss aa");
StringBuilder std = new StringBuilder(s);
if(std.toString().contains("P"))
{
   std.insert(std.indexOf("P"), " ");
}else{
   std.insert(std.indexOf("A"), " ");
}
   
String.format("%tT",df.parse(std.toString())));