Parse Datetime in Multiple Formats

Parse datetime in multiple formats

You should consider requiring a timezone.
1 doesn't need it, but #2 and #3 do.

public DateTime ParseRequestDate()
{
// https://stackoverflow.com/questions/2883576/how-do-you-convert-epoch-time-in-c

CultureInfo enUS = new CultureInfo("en-US");

var dt = "1374755180";
//var dt = "7/25/2013 6:37:31 PM";
//var dt = "2013-07-25 14:26:00";

DateTime dateValue;
long dtLong;

// Scenario #1
if (long.TryParse(dt, out dtLong))
return dtLong.FromUnixTime();

// Scenario #2
if (DateTime.TryParseExact(dt, "MM/dd/yyyy hh:mm:ss tt", enUS, DateTimeStyles.None, out dateValue))
return dateValue;

// Scenario #3
if (DateTime.TryParseExact(dt, "yyyy-MM-dd hh:mm:ss", enUS, DateTimeStyles.None, out dateValue))
return dateValue;

throw new SomeException("Don't know how to parse...");
}

EDIT
As Matt Johnson points out, DateTime.TryParseExact accepts an array of format strings.
2 & 3 could be condensed.

public DateTime ParseRequestDate()
{
// https://stackoverflow.com/questions/2883576/how-do-you-convert-epoch-time-in-c

CultureInfo enUS = new CultureInfo("en-US");

var dt = "1374755180";
//var dt = "7/25/2013 6:37:31 PM";
//var dt = "2013-07-25 14:26:00";

DateTime dateValue;
long dtLong;

// Scenario #1
if (long.TryParse(dt, out dtLong))
return dtLong.FromUnixTime();

// Scenario #2 & #3
var formatStrings = new string[] { "MM/dd/yyyy hh:mm:ss tt", "yyyy-MM-dd hh:mm:ss" };
if (DateTime.TryParseExact(dt, formatStrings, enUS, DateTimeStyles.None, out dateValue))
return dateValue;

throw new SomeException("Don't know how to parse...");
}

The epoch conversion I borrowed from another question.
(An extension method)

public static class MyExtensions
{
public static DateTime FromUnixTime(this long unixTime)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return epoch.AddSeconds(unixTime);
}
}

Parse Date from string present in multiple formats into datetime format

dateutil's parser can help:

from dateutil import parser

for d in ["20200618", "18-june-2020"]:
print(parser.parse(d))

2020-06-18 00:00:00
2020-06-18 00:00:00

Powershell Datetime::Parseexact with multiple formats

You are doing it just fine, the only problem is that @(..) is object[] not string[]:

$datesToTest = '1605221412', '09/02/2022', '02-09-2022'
$formats = 'yyMMddHHmm', 'yyyyMMddHHmm', 'dd/MM/yyyy', 'dd-MM-yyyy'
$datesToTest | ForEach-Object {
[System.DateTime]::ParseExact($_, [string[]]$formats, [cultureinfo]::InvariantCulture)
}
  • See ParseExact(String, String[], IFormatProvider, DateTimeStyles)

How to format date string via multiple formats in python

Try each format and see if it works:

from datetime import datetime

def try_parsing_date(text):
for fmt in ('%Y-%m-%d', '%d.%m.%Y', '%d/%m/%Y'):
try:
return datetime.strptime(text, fmt)
except ValueError:
pass
raise ValueError('no valid date format found')

How to parse custom multiple Date formats in Java

You can use [] to define the optional parts within a pattern. Additionally you need to set defaults to not get an exception when no time is supplied.

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("yyMMdd['h'HH]")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter();

String dateString1 = "201028h05";
LocalDateTime date1 = LocalDateTime.parse(dateString1, formatter);
System.out.println(date1);

String dateString2 = "201028";
LocalDateTime date2 = LocalDateTime.parse(dateString2, formatter);
System.out.println(date2);

Output:

2020-10-28T05:00
2020-10-28T00:00

How to parse dates in multiple formats using SimpleDateFormat

You'll need to use a different SimpleDateFormat object for each different pattern. That said, you don't need that many different ones, thanks to this:

Number: For formatting, the number of pattern letters is the minimum number of digits, and shorter numbers are zero-padded to this amount. For parsing, the number of pattern letters is ignored unless it's needed to separate two adjacent fields.

So, you'll need these formats:

  • "M/y" (that covers 9/09, 9/2009, and 09/2009)
  • "M/d/y" (that covers 9/1/2009)
  • "M-d-y" (that covers 9-1-2009)

So, my advice would be to write a method that works something like this (untested):

// ...
List<String> formatStrings = Arrays.asList("M/y", "M/d/y", "M-d-y");
// ...

Date tryParse(String dateString)
{
for (String formatString : formatStrings)
{
try
{
return new SimpleDateFormat(formatString).parse(dateString);
}
catch (ParseException e) {}
}

return null;
}

How to Parse different Date formats from String in Java (FAQ)

Avoid legacy date-time classes

The old Date, Calendar, and SimpleDateFormat classes are an awful sour mess of poor design. Never use them. Now supplanted by the java.time classes.

Parsing

First test if input string equals "null".

Next, parse the first format with simply LocalDate.parse( "1987-03-23" ) and trap for exception. That standard ISO 8601 format is handled by default, so no need to specify a formatting pattern.

Lastly, define a formatting pattern DateTimeFormatter.ofPatten( "dd-MM-uuuu" ) and parse with that, calling LocalDate.parse( input , formatter ). Trap for exception.

If all those fail, you have unexpected inputs.

Generating strings

Once you have a LocalDate object in hand, generate a string using LocalDate.format where you pass a DateTimeFormatter. You can define a formatting pattern as seen above. Or, you can call DateTimeFormatter.ofLocalizedDate to let java.time automatically localize for you.

Search Stack Overflow

This has been covered many many times already. Search Stack Overflow for these class names, to see more detail and more code.

I suggest using a search engine with site:stackoverflow.com criteria as the built-in search feature in Stack Overflow is weak and tends to ignore Answers, biasing towards only Questions.

For example, do this:

https://duckduckgo.com/?q=site%3Astackoverflow.com+java+DateTimeFormatter&t=h_&ia=web


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

  • Java SE 8, Java SE 9, Java SE 10, and later

    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and Java SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • Later versions of Android bundle implementations of the java.time classes.
    • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.



Related Topics



Leave a reply



Submit