Asked  8 Months ago    Answers:  5   Viewed   39 times

With a date string of Apr 30, 2010, how can I parse the string into 2010-04-30 using PHP?

 Answers

27

Try http://php.net/manual/en/function.strtotime.php to convert to a timestamp and then http://www.php.net/manual/en/function.date.php to get it in your own format.

Wednesday, March 31, 2021
 
pwaring
answered 8 Months ago
17
std::tm tm = {};
std::stringstream ss("Jan 9 2014 12:35:34");
ss >> std::get_time(&tm, "%b %d %Y %H:%M:%S");
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&tm));

GCC prior to version 5 doesn't implement std::get_time. You should also be able to write:

std::tm tm = {};
strptime("Thu Jan 9 2014 12:35:34", "%a %b %d %Y %H:%M:%S", &tm);
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&tm));
Wednesday, June 2, 2021
 
CMOS
answered 5 Months ago
78

why not use date() just like below,try this

$t = strtotime('20130409163705');
echo date('d/m/y H:i:s',$t);

and will be output

09/04/13 16:37:05
Monday, June 14, 2021
 
mopsyd
answered 5 Months ago
98

The call to ofLocalizedDateTime() can be removed, because in the end you call ofPattern(), creating another formatter with a totally different pattern (and the pattern returned by ofLocalizedDateTime(FormatStyle.FULL) is very different from just month year, so that's not really what you want).

Another detail is that Mayo is the full month name, so the pattern must be MMMM (check the javadoc for more details). Also, the DateTimeFormatter by default accepts only lowercase names (at least in the tests I've made with Spanish locale), so you must set the formatter to be case insensitive.

You can do that by using a java.time.format.DateTimeFormatterBuilder:

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
    // case insensitive
    .parseCaseInsensitive()
    // pattern with full month name (MMMM)
    .appendPattern("MMMM yyyy")
    // set locale
    .toFormatter(new Locale("es", "ES"));
// now it works
fmt.parse("Mayo 2017");

Optionally, you can directly parse it to a java.time.YearMonth object, as it seems to be the best choice for this case (because the input has only year and month):

YearMonth ym = YearMonth.parse("Mayo 2017", fmt);
System.out.println(ym); // 2017-05

Default values

When the input doesn't have all the fields, SimpleDateFormat simply uses some defaults for them. In this case, the input has only year and month, so the parsed Date will be equivalent to the parsed month/year, but the day will be set to 1 and the time to midnight (at the JVM default timezone).

The new API is very strict about that and doesn't create default values unless you tell it to do so. One way to configure it is to use parseDefaulting with a java.time.temporal.ChronoField:

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
    // case insensitive
    .parseCaseInsensitive()
    // pattern with full month name (MMMM)
    .appendPattern("MMMM yyyy")
    // default value for day of month
    .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
    // default value for hour
    .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
    // default value for minute
    .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
    // set locale
    .toFormatter(new Locale("es", "ES"));

With this, you can parse it to a LocalDateTime and the missing fields will be assigned to the respective default values:

LocalDateTime dt = LocalDateTime.parse("Mayo 2017", fmt);
System.out.println(dt); // 2017-05-01T00:00

If you need to get a java.util.Date with the same value as the one created by SimpleDateFormat, you can convert this LocalDateTime to the JVM default timezone and then convert it to Date:

Date javaUtilDate = Date.from(dt.atZone(ZoneId.systemDefault()).toInstant());

Note that I had to explicity use the JVM default timezone (ZoneId.systemDefault()), which is implicity used by SimpleDateFormat.


Another alternative is to manually set the values in the YearMonth value:

// in this case, the formatter doesn't need the default values
YearMonth ym = YearMonth.parse("Mayo 2017", fmt);
ZonedDateTime z = ym
    // set day of month to 1
    .atDay(1)
    // midnight at JVM default timezone
    .atStartOfDay(ZoneId.systemDefault());
Date javaUtilDate = date.from(z.toInstant());

The default timezone can be changed without notice, even at runtime, so it's better to always make it explicit which one you're using.

The API uses IANA timezones names (always in the format Region/City, like America/New_York or Europe/Berlin), so you can call ZoneId.of("America/New_York") for example. Avoid using the 3-letter abbreviations (like CST or PST) because they are ambiguous and not standard.

You can get a list of available timezones (and choose the one that fits best your system) by calling ZoneId.getAvailableZoneIds().

Wednesday, August 4, 2021
 
Noctis
answered 3 Months ago
57

explode will do the trick for that:

$pieces = explode("/", $date);
$d = $pieces[1];
$m = $pieces[0];
$y = $pieces[2];

Alternatively, you could do it in one line (see comments - thanks Lucky):

list($m, $d, $y) = explode("/", $date);
Thursday, August 5, 2021
 
Pwner
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share