在Java中格式化小时为20小时10分钟5000秒为20小时10分钟10秒。

huangapple go评论76阅读模式
英文:

Formatting hour in java 20h 10m 5000s to 20h 10m 10s

问题

我正在尝试创建一个小程序,我们提供一个错误的时间,例如:20小时 10分钟 5000秒,然后将其转换为返回给我 20小时 10分钟 50秒。但是很抱歉,我无法展示给您代码,以便查看是否能够帮助我,非常感谢:)

import java.util.Date;
import java.text.SimpleDateFormat;
import javax.swing.JOptionPane;

public class EejercicioBasico3 {
public static void main(String[] args) {

	Date date = new Date();
	SimpleDateFormat dateForm = new SimpleDateFormat("HH:mm:ss");

    String UserDate = dateForm.format(JOptionPane.showInputDialog("Escriba una hora en formato hh-mm-ss"));
    
    System.out.println(date);
    System.out.println(UserDate);

}

}


<details>
<summary>英文:</summary>

I am trying to create a small program that we give a wrong time for example: 20h 10m 5000s and that transforms it giving me back 20h 10m 50s. But I am unable to show you the code to see if you can help me, thank you very much :)

import java.util.Date;
import java.text.SimpleDateFormat;
import javax.swing.JOptionPane;

public class EejercicioBasico3 {
public static void main(String[] args) {

	Date date = new Date();
	SimpleDateFormat dateForm = new SimpleDateFormat(&quot;HH:mm:ss&quot;);

    String UserDate = dateForm.format(JOptionPane.showInputDialog(&quot;Escriba una hora en formato hh-mm-ss&quot;));
    
    System.out.println(date);
    System.out.println(UserDate);

}

}


</details>


# 答案1
**得分**: 2

## 移除多余的数字

我从你的问题和评论中理解到,你假设用户可能会因失误而输入过多的数字。我进一步假设每个数字可能在从0或00到59的区间内,任何使数字大于59或超过两位数的数字都应该被移除。这可能不是完美的解决方案,但可以让你开始。

```java
String inputTimeString = "20h 10m 5000s";
String outputTimeString = inputTimeString.replaceAll("([6-9]|[0-5]\\d)\\d+", "$1");
System.out.println(outputTimeString);

输出结果为:

> 20h 10m 50s

正则表达式首先匹配在范围6-9内的数字,或者以0到5开头的两位数字,以确保我们最多只有59。这个数字或这些数字被捕获为一个组,正则表达式中使用圆括号将组括起来。在组后,匹配任意数量的多余数字。在替换字符串中,我使用$1来表示这些数字应该被替换为捕获组1中匹配的内容(在这种情况下是唯一的捕获组)。

再试一个例子:

String inputTimeString = "60h 010m 777s";

输出结果为:

> 6h 01m 7s

备注: 如果这是学校的基础练习,你的老师可能会有另一种解决方案,但你可以更好地判断。如果你还没有学习正则表达式,那么最好不要提交使用正则表达式的解决方案。也许你应该遍历输入字符串,并将那些合适的字符添加到一个字符串缓冲区中,用于收集输出。

将多余的秒转换为分钟和小时

如果你想要将超过59秒的多余秒数转换为分钟和小时,可以使用Duration类:

String isoTimeString = "PT" + inputTimeString.replaceAll(" ", "");
Duration dur = Duration.parse(isoTimeString);
String outputTimeString = String.format("%dh %dm %ds",
        dur.toHours(), dur.toMinutesPart(), dur.toSecondsPart());
        
System.out.println(outputTimeString);

输出结果为:

> 21h 33m 20s

Duration.parse() 需要 ISO 8601 格式。这可以通过在你的格式前加上 PT(表示时间段)并去除空格来获得。String.format() 调用重新生成了你的格式。

始终避免使用 Date 和 SimpleDateFormat

你尝试使用的 SimpleDateFormatDate 类设计不佳,已经过时,并且从未适用于这样的任务。我建议你永远不要使用它们,而应始终使用现代的 Java 日期和时间 API - java.time 来处理时间。Duration 类是 java.time 的一部分。

链接

英文:

Removing excess digits

I tend to understand from your question and comments that you are assuming that the user may type too many digits by mistake. I am further assuming that each number may be in the interval from 0 or 00 to 59, and any digits that make the number greater than 59 or wider than two digits are to be removed. It’s probably not perfect, but may get you started.

	String inputTimeString = &quot;20h 10m 5000s&quot;;
	String outputTimeString
			= inputTimeString.replaceAll(&quot;([6-9]|[0-5]\\d)\\d+&quot;, &quot;$1&quot;);
	System.out.println(outputTimeString);

Output is:

> 20h 10m 50s

The regular expression first matches either a digit in the range 6 – 9 or two digits starting with 0 through 5 to ensure that we got at most 59. This or these digits are captured as a group using round brackets around the group in the regexp. After the group any number of excess digits is matched. In the replacement string I use $1 to denote that the digits should be replaced with just what was matched in capturing group no. 1 (the only capturing group in this case).

Try another example:

	String inputTimeString = &quot;60h 010m 777s&quot;;

> 6h 01m 7s

Reservation: If this is a basic exercise from school, your teacher may have another solution in mind, but you can judge that better. If you haven’t learnt regular expressions, you probably should not hand in a solution that uses them. Maybe you were expected to iterate through the input string and add characters that are OK to a string buffer where you collect your output.

Converting excess seconds to minutes and hours

If instead you want excess seconds — over 59 seconds — converted to minutes and hours, use the Duration class:

	String isoTimeString = &quot;PT&quot; + inputTimeString.replaceAll(&quot; &quot;, &quot;&quot;);
	Duration dur = Duration.parse(isoTimeString);
	String outputTimeString = String.format(&quot;%dh %dm %ds&quot;,
			dur.toHours(), dur.toMinutesPart(), dur.toSecondsPart());
	
	System.out.println(outputTimeString);

> 21h 33m 20s

Duration.parse() requires ISO 8601 format. This is obtained from your format by prefixing PT (think period of time) and removing the spaces. The String.format() call reproduces your format.

Always avoid Date and SimpleDateFormat

The classes you were trying to use, SimpleDateFormat and Date, are poorly designed and long outdated and were never meant for a job like this. I recommmend that you never use them and always use java.time, the modern Java date and time API, for your time work. The Duration class is part of java.time.

答案2

得分: 1

依我看,底线就是...不要接受这样的输入:20h 10m 5000s。虽然数据是通过一个输入对话框窗口提供的,但仍然可以验证其是否包含所需的格式(在对话框中明确显示为示例),如果不是,则通知用户重新输入。您的代码实际上不应该适应每个打字错误并自动更正。但它应该确定存在打字错误,并通知用户进行更正或完全放弃输入的数据。您的应用程序制定了规则,而不是用户(不过不幸的是,这可能并非对所有情况都适用)。这可能听起来很直接,但是你不能使每件事都白痴化,因为明天,肯定会有一个更好的白痴。让那个白痴做对。

确定您的应用程序的时间输入规则:

  • 时间应由三个特定单位组成:小时分钟
  • 时间采用24小时制,这意味着没有上午或下午之分。
  • 每个时间单位(小时、分钟或秒)应由两个整数数字组成(例如:15-32-05)。
  • 应该应用分隔符字符来分隔每个时间单位。在这种情况下,允许使用连字符(-)或减号字符。

String userTime = "";
while (userTime.isEmpty()) {
    userTime = JOptionPane.showInputDialog(null, "<html>Enter a time in "
                + "<font color=red><b>hh-mm-ss</b></font> format:<br><br></html>");
    if (userTime == null) {
        JOptionPane.showMessageDialog(null, "Time entry Canceled!", "Entry Canceled",
                JOptionPane.WARNING_MESSAGE);
        return;
    }
    if (!userTime.matches(
               "^([0-1][0-9][-]|[2][0-3][-])([0-5][0-9][-])([0-5][0-9])$")) {
        JOptionPane.showMessageDialog(null, "Invalid Time format supplied!", 
                                "Invalid Entry", JOptionPane.WARNING_MESSAGE);
        userTime = "";
    }
}

String[] timeUnits = userTime.split("-");
String time = new StringBuilder("").append(timeUnits[0]).append("h ")
                 .append(timeUnits[1]).append("m ").append(timeUnits[2])
                 .append("s").toString();
JOptionPane.showMessageDialog(null, "<html>User supplied the time of:<br><br>"
        + "<center><font color=blue><b>" + time + "</b></font></center></html>",
        "Invalid Entry", JOptionPane.INFORMATION_MESSAGE);

显然您不需要在循环中执行此类操作,但我相信您已经理解了。

英文:

In my opinion the bottom line would be...just don't accept an entry of: 20h 10m 5000s. Although the data is supplied through an Input Dialog window it can still be validated to contain the desired format (which is clearly shown as an example within the dialog) and if it isn't, inform the User to enter it again. Your code really shouldn't need to accommodate every typo and automatically correct it. It should however determine that there is a typo and inform the User to correct it or discard the input data altogether. Your application sets the rules, not the User (unfortunately however this may not be the case for everything). This may seem blunt but, you can't make everything idiot proof because tomorrow, there will just be a better idiot. Make the idiot do it right.

Determine your application's Time Entry rules:

  • Time is to be in three specific units: Hours, Minutes, and
    Seconds.
  • Time is in 24 hour format meaning there is no such thing as AM or PM.
  • Each time unit (Hour, Minute, or Second) is to be comprised of two integer digits (ex: 15-32-05).
  • A separator character must be applied to separate each time
    unit. The allowable character in this case is the Hyphen (-) or Minus character.

String userTime = &quot;&quot;;
while (userTime.isEmpty()) {
    userTime = JOptionPane.showInputDialog(null, &quot;&lt;html&gt;Enter a time in &quot;
                + &quot;&lt;font color=red&gt;&lt;b&gt;hh-mm-ss&lt;/b&gt;&lt;/font&gt; format:&lt;br&gt;&lt;br&gt;&lt;/html&gt;&quot;);
    if (userTime == null) {
        JOptionPane.showMessageDialog(null, &quot;Time entry Canceled!&quot;, &quot;Entry Canceled&quot;,
                JOptionPane.WARNING_MESSAGE);
        return;
    }
    if (!userTime.matches(
               &quot;^([0-1][0-9][-]|[2][0-3][-])([0-5][0-9][-])([0-5][0-9])$&quot;)) {
        JOptionPane.showMessageDialog(null, &quot;Invalid Time format supplied!&quot;, 
                                &quot;Invalid Entry&quot;, JOptionPane.WARNING_MESSAGE);
        userTime = &quot;&quot;;
    }
}

String[] timeUnits = userTime.split(&quot;-&quot;);
String time = new StringBuilder(&quot;&quot;).append(timeUnits[0]).append(&quot;h &quot;)
                 .append(timeUnits[1]).append(&quot;m &quot;).append(timeUnits[2])
                 .append(&quot;s&quot;).toString();
JOptionPane.showMessageDialog(null, &quot;&lt;html&gt;User supplied the time of:&lt;br&gt;&lt;br&gt;&quot;
        + &quot;&lt;center&gt;&lt;font color=blue&gt;&lt;b&gt;&quot; + time + &quot;&lt;/b&gt;&lt;/font&gt;&lt;/center&gt;&lt;/html&gt;&quot;,
        &quot;Invalid Entry&quot;, JOptionPane.INFORMATION_MESSAGE);

Obviously you don't need to do this sort of thing in a loop but you get the idea I'm sure.

huangapple
  • 本文由 发表于 2020年10月18日 18:35:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/64412302.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定