MoonKnight MoonKnight - 2 years ago 125
C# Question

DateTime Manipulation in C# vs Java

I'm new to Java. I have a time I am getting from a web-page, this is in the "hh:mm" format (not 24 hour). This comes to me as a string. I then want to combine this string with todays date in order to make a Java

Date
I can use.

In C#:

string s = "5:45 PM";
DateTime d;
DateTime.TryParse(s, out d);


in Java I have attempted:

String s = "5:45 PM";
Date d = new Date(); // Which instantiates with the current date/time.

String[] arr = s.split(" ");
boolean isPm = arr[1].compareToIgnoreCase("PM") == 0;

arr = arr[0].split(":");
int hours = Integer.parseInt(arr[0]);
d.setHours(isPm ? hours + 12 : hours);
d.setMinutes(Integer.parseInt(arr[1]));
d.setSeconds(0);


Is there a better way to achieve what I want?

Answer Source

Is there a better way to achieve what I want?

Absolutely - in both .NET and in Java, in fact. In .NET I'd (in a biased way) recommend using Noda Time so you can represent just a time of day as a LocalTime, parsing precisely the pattern you expect.

In Java 8 you can do the same thing with java.time.LocalTime:

import java.time.*;
import java.time.format.*;

public class Test {
    public static void main(String[] args) {
        String text = "5:45 PM";
        DateTimeFormatter format = DateTimeFormatter.ofPattern("h:mm a");
        LocalTime time = LocalTime.parse(text, format);
        System.out.println(time);
    }
}

Once you've parsed the text you've got into an appropriate type, you can combine it with other types. For example, to get a ZonedDateTime in the system time zone, using today's date and the specified time of day, you might use:

ZonedDateTime zoned = ZonedDateTime.now().with(time);

That uses the system time zone and clock by default, making it hard to test - I'd recommend passing in a Clock for testability.

(The same sort of thing is available in Noda Time, but slightly differently. Let me know if you need details.)

I would strongly recommend against using java.util.Date, which just represents an instant in time and has an awful API.

The key points here are:

  • Parse the text with a well-specified format
  • Parse the text into a type that represents the information it conveys: a time of day
  • Combine that value with another value which should also be carefully specified (in terms of clock and time zone)

All of these will lead to clear, reliable, testable code. (And the existing .NET code doesn't meet any of those bullet points, IMO.)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download