• Log InLog In
  • Register
Liquid`
Team Liquid Liquipedia
EST 02:04
CET 08:04
KST 16:04
  • Home
  • Forum
  • Calendar
  • Streams
  • Liquipedia
  • Features
  • Store
  • EPT
  • TL+
  • StarCraft 2
  • Brood War
  • Smash
  • Heroes
  • Counter-Strike
  • Overwatch
  • Liquibet
  • Fantasy StarCraft
  • TLPD
  • StarCraft 2
  • Brood War
  • Blogs
Forum Sidebar
Events/Features
News
Featured News
Rongyi Cup S3 - Preview & Info3herO wins SC2 All-Star Invitational12SC2 All-Star Invitational: Tournament Preview5RSL Revival - 2025 Season Finals Preview8RSL Season 3 - Playoffs Preview0
Community News
Weekly Cups (Jan 12-18): herO, MaxPax, Solar win0BSL Season 2025 - Full Overview and Conclusion8Weekly Cups (Jan 5-11): Clem wins big offline, Trigger upsets4$21,000 Rongyi Cup Season 3 announced (Jan 22-Feb 7)25Weekly Cups (Dec 29-Jan 4): Protoss rolls, 2v2 returns7
StarCraft 2
General
PhD study /w SC2 - help with a survey! herO wins SC2 All-Star Invitational Oliveira Would Have Returned If EWC Continued StarCraft 2 not at the Esports World Cup 2026 [Short Story] The Last GSL
Tourneys
$21,000 Rongyi Cup Season 3 announced (Jan 22-Feb 7) OSC Season 13 World Championship $70 Prize Pool Ladder Legends Academy Weekly Open! SC2 All-Star Invitational: Jan 17-18 Sparkling Tuna Cup - Weekly Open Tournament
Strategy
Simple Questions Simple Answers
Custom Maps
[A] Starcraft Sound Mod
External Content
Mutation # 510 Safety Violation Mutation # 509 Doomsday Report Mutation # 508 Violent Night Mutation # 507 Well Trained
Brood War
General
[ASL21] Potential Map Candidates Which foreign pros are considered the best? Gypsy to Korea BGH Auto Balance -> http://bghmmr.eu/ Fantasy's Q&A video
Tourneys
[Megathread] Daily Proleagues Azhi's Colosseum - Season 2 Small VOD Thread 2.0 [BSL21] Non-Korean Championship - Starts Jan 10
Strategy
Current Meta Simple Questions, Simple Answers Soma's 9 hatch build from ASL Game 2 Game Theory for Starcraft
Other Games
General Games
Nintendo Switch Thread Battle Aces/David Kim RTS Megathread Stormgate/Frost Giant Megathread Beyond All Reason Awesome Games Done Quick 2026!
Dota 2
Official 'what is Dota anymore' discussion
League of Legends
Heroes of the Storm
Simple Questions, Simple Answers Heroes of the Storm 2.0
Hearthstone
Deck construction bug Heroes of StarCraft mini-set
TL Mafia
Vanilla Mini Mafia Mafia Game Mode Feedback/Ideas
Community
General
US Politics Mega-thread Russo-Ukrainian War Thread European Politico-economics QA Mega-thread Canadian Politics Mega-thread NASA and the Private Sector
Fan Clubs
The herO Fan Club! The IdrA Fan Club
Media & Entertainment
Anime Discussion Thread [Manga] One Piece
Sports
2024 - 2026 Football Thread
World Cup 2022
Tech Support
Computer Build, Upgrade & Buying Resource Thread
TL Community
The Automated Ban List
Blogs
How Esports Advertising Shap…
TrAiDoS
My 2025 Magic: The Gathering…
DARKING
Life Update and thoughts.
FuDDx
How do archons sleep?
8882
James Bond movies ranking - pa…
Topin
Customize Sidebar...

Website Feedback

Closed Threads



Active: 1430 users

PHP - Date Format Check

Blogs > tofucake
Post a Reply
1 2 Next All
tofucake
Profile Blog Joined October 2009
Hyrule19190 Posts
Last Edited: 2010-07-23 14:31:29
July 20 2010 16:15 GMT
#1
I needed to make sure dates were in Y-m-d format for some calculations at work, so I wrote this up. It's not perfect, but it's quite enough to handle my needs. So, for anyone who uses PHP and needs to make sure dates are in Y-m-d format (for strtotime() or whatever reason), I grant you checkDateFormat(). It checks for valid formatted dates with space, hyphen, period, or slash separation.

function checkDateFormat($date, $empty = '0', $sep = '/')
{
$date = preg_replace('/[^\d\-\. \/]/', '', $date); // remove non-numeric and non-date separaters

$check = preg_split('/[ \-\.\/]/', $date);
if(empty($check)) return '0';

foreach($check as &$item)
$item = str_pad($item, 2, '0', STR_PAD_LEFT);
$date = implode('-', $check);

// matches for all format dates, with space, hyphen, period, or slash separators
// correct format needed is Y-m-d
// 100 is used as the final check to keep room open for later additions
$patterns = array(
0 => '/(9999)[- \.\/](09)[- \.\/](09)/', // one of the many different "blank" values used
1 => '/(0[1-9]|1[012])[- \.\/](0[1-9]|1[012])[- \.\/](\d{4,4})/', // unknown d-m order, Y at end
2 => '/(\d{4,4})[- \.\/](0[1-9]|1[012])[- \.\/](0[1-9]|1[012])/', // unknown d-m order, Y at front
3 => '/(0[1-9]|1[012])[- \.\/](0[1-9]|[12][0-9]|3[01])[- \.\/](\d{4,4})/', // m-d-Y
4 => '/(\d{4,4})[- \.\/](0[1-9]|1[012])[- \.\/](0[1-9]|[12][0-9]|3[01])/', // Y-m-d (aka already correct)
5 => '/(0[1-9]|[12][0-9]|3[01])[- \.\/](0[1-9]|1[012])[- \.\/](\d{4,4})/', // d-m-Y
6 => '/(\d{4,4})[- \.\/](0[1-9]|[12][0-9]|3[01])[- \.\/](0[1-9]|1[012])/', // Y-d-m
99 => '/ |[s(\302\240|\240)]+|[W]+/', // blank, empty, or placeholder
100 => '/(\d{2,2})[- \.\/](\d{2,2})[- \.\/](\d{2,2})/' // unknown all double digits
);

// for unknown d-m order assume month is first
$replace = array(
0 => $empty,
1 => "$3{$sep}$1{$sep}$2", // unknown d-m order, Y at end -> Y-m-d
2 => "$1{$sep}$2{$sep}$3", // unknown d-m order, Y at front -> Y-m-d
3 => "$3{$sep}$1{$sep}$2", // m-d-Y -> Y-m-d
4 => "$1{$sep}$2{$sep}$3", // Y-m-d -> Y-m-d
5 => "$3{$sep}$2{$sep}$1", // d-m-Y -> Y-m-d
6 => "$3{$sep}$1{$sep}$2", // Y-d-m -> Y-m-d
99 => "$0",
100 => $empty
);

foreach($patterns as $index => $pattern)
if(preg_match($pattern, $date))
return preg_replace($pattern, $replace[$index], $date);

return $empty;
}


Yeah, the regular expressions are long, but whatever. I replaced tabs with 2 spaces because it was huge (I develop with tabstop = 4, but the most common setting is 8, which is ugly).

if you want to return the original date, change $replace as follows:
100 => "$1-$2-$3"

Easy, eh?

I'll explain it more thoroughly later (ie: when I'm not at work) if anyone wants me to.

[update]
Added in checks for single digits (again, my users cannot be trusted!) and some other checks

Liquipediaasante sana squash banana
Dance.jhu
Profile Blog Joined May 2010
United States292 Posts
July 20 2010 16:46 GMT
#2
Yea, that looks right......
It is what it is...
Cambium
Profile Blog Joined June 2004
United States16368 Posts
July 20 2010 16:50 GMT
#3
More like "Regex - Date Format Check"
When you want something, all the universe conspires in helping you to achieve it.
gen.Sun
Profile Blog Joined October 2009
United States539 Posts
July 20 2010 17:00 GMT
#4
stackoverflow.com
tofucake
Profile Blog Joined October 2009
Hyrule19190 Posts
Last Edited: 2010-07-20 17:39:13
July 20 2010 17:38 GMT
#5
On July 21 2010 01:46 Dance.jhu wrote:
Yea, that looks right......

^^

On July 21 2010 01:50 Cambium wrote:
More like "Regex - Date Format Check"

Nah. Regex is a way of expressing patterns, you still need Perl/PHP/somelanguagethathandlesregex to use them. But yeah, it's more regex than PHP :X


On July 21 2010 02:00 gen.Sun wrote:
stackoverflow.com

Is that a nice way of saying "gtfo"?
Liquipediaasante sana squash banana
Louder
Profile Blog Joined September 2002
United States2276 Posts
July 20 2010 18:59 GMT
#6
What is the context of this solution - where's the data coming from? If you can't assume users are entering dates in just one format, then you can't assume they're not going to put the day the day before the month in all ambiguous dates. The clear problem here is the lack of disambiguation with m-d/d-m dates.
tofucake
Profile Blog Joined October 2009
Hyrule19190 Posts
July 20 2010 19:06 GMT
#7
True, but the data is coming from America (not really what you asked, but eh?), so dates are typically m-d-Y.

As for who's entering it, right now there's only a few people in our office, but this project will be sold to others. My code (elsewhere) checks the whole ambiguous date thing in other ways.
Liquipediaasante sana squash banana
Pryce
Profile Joined February 2009
Canada7 Posts
Last Edited: 2010-07-20 20:05:31
July 20 2010 19:58 GMT
#8
There's not really a need for such complicated logic. strtotime accepts any english date format so you could use something like:

$time = strtotime($date);
if ($time < 0) throw new Exception("Invalid Date Format: $date");
return date('Y-m-d', $time);

If you're running PHP 5.2 or newer, you can also use the DateTime class.
return new DateTime($date); // throws an exception if your date is invalid
R1CH
Profile Blog Joined May 2007
Netherlands10341 Posts
July 20 2010 20:04 GMT
#9
I don't see why checkdate() wouldn't work for this if you expect the arguments in a certain order. This seems like more of an input problem than a parsing problem.
AdministratorTwitter: @R1CH_TL
TL+ Member
Louder
Profile Blog Joined September 2002
United States2276 Posts
July 20 2010 23:42 GMT
#10
The dates are presumably in text... only reason you would do this
gen.Sun
Profile Blog Joined October 2009
United States539 Posts
July 21 2010 01:14 GMT
#11
On July 21 2010 02:38 tofucake wrote:
Show nested quote +
On July 21 2010 02:00 gen.Sun wrote:
stackoverflow.com

Is that a nice way of saying "gtfo"?


It's just a better place to ask programming questions, it'll be both faster and better.
aers *
Profile Joined January 2009
United States1210 Posts
July 21 2010 02:18 GMT
#12
He's not asking a question, though.
tofucake
Profile Blog Joined October 2009
Hyrule19190 Posts
July 21 2010 12:02 GMT
#13
On July 21 2010 04:58 Pryce wrote:
There's not really a need for such complicated logic. strtotime accepts any english date format so you could use something like:

$time = strtotime($date);
if ($time < 0) throw new Exception("Invalid Date Format: $date");
return date('Y-m-d', $time);

If you're running PHP 5.2 or newer, you can also use the DateTime class.
return new DateTime($date); // throws an exception if your date is invalid

strtotime() is used, but it doesn't accept any format. This is used for financial transactions (well, displaying them..thousands of them), so a bunch of "Invalid Date Format: $date" displays is not acceptable.


On July 21 2010 05:04 R1CH wrote:
I don't see why checkdate() wouldn't work for this if you expect the arguments in a certain order. This seems like more of an input problem than a parsing problem.

The people inputting the dates cannot be trusted.


On July 21 2010 10:14 gen.Sun wrote:
Show nested quote +
On July 21 2010 02:38 tofucake wrote:
On July 21 2010 02:00 gen.Sun wrote:
stackoverflow.com

Is that a nice way of saying "gtfo"?


It's just a better place to ask programming questions, it'll be both faster and better.
I'm not asking a question, I'm posting a solution to a possible question. Also, I literally just forgot what I was going to say.
Liquipediaasante sana squash banana
Louder
Profile Blog Joined September 2002
United States2276 Posts
July 21 2010 16:49 GMT
#14
On July 21 2010 21:02 tofucake wrote:
Show nested quote +
On July 21 2010 04:58 Pryce wrote:
There's not really a need for such complicated logic. strtotime accepts any english date format so you could use something like:

$time = strtotime($date);
if ($time < 0) throw new Exception("Invalid Date Format: $date");
return date('Y-m-d', $time);

If you're running PHP 5.2 or newer, you can also use the DateTime class.
return new DateTime($date); // throws an exception if your date is invalid

strtotime() is used, but it doesn't accept any format. This is used for financial transactions (well, displaying them..thousands of them), so a bunch of "Invalid Date Format: $date" displays is not acceptable.


See, I just assumed that you were working with large blocks of text, because otherwise regular expressions are one of the worst ways to solve this problem. strtotime() will work with any of the date formats you test for, and will make the same assumption your code does for ambiguous month/day formats. But whatever floats your boat.
tofucake
Profile Blog Joined October 2009
Hyrule19190 Posts
July 21 2010 19:55 GMT
#15
Yeah I was using just strtotime() before, and it was returning 0 for about half the dates. When I started using my version, all the dates are formatted correctly (and all the calculations are correct).
Liquipediaasante sana squash banana
tofucake
Profile Blog Joined October 2009
Hyrule19190 Posts
July 23 2010 14:32 GMT
#16
Shameless bump! I updated my original with a few more checks. Works better since I found some more formats in the database :|
Liquipediaasante sana squash banana
konadora *
Profile Blog Joined February 2009
Singapore66358 Posts
July 23 2010 14:43 GMT
#17
php looks hard ;;
POGGERS
tofucake
Profile Blog Joined October 2009
Hyrule19190 Posts
July 23 2010 16:06 GMT
#18
It's really not. Most of that is actually Perl (which is very difficult to read if you're not used to it). The only reason I do something this complicated is because I didn't write the original stuff, and that allowed for (and does) a lot of dumb things.
Liquipediaasante sana squash banana
Dycedarg
Profile Joined July 2010
United States12 Posts
July 23 2010 18:16 GMT
#19
Is this for users to enter dates into a text box and then you check it? If so why go through this if you can just restrict the users from using text boxes and just have drop down boxes or a calendar of some sort. That way you never need to worry about bad user inputs. Its usually better to just not allow users the freedom to do anything they want because they can and WILL break it.
tofucake
Profile Blog Joined October 2009
Hyrule19190 Posts
July 23 2010 18:19 GMT
#20
Because there are already thousands upon thousands of dates in the database. I didn't write the original site, I've come in to fix it.
Liquipediaasante sana squash banana
1 2 Next All
Please log in or register to reply.
Live Events Refresh
Replay Cast
00:00
Rongyi Cup S3 - Group D
LiquipediaDiscussion
[ Submit Event ]
Live Streams
Refresh
StarCraft 2
NeuroSwarm 137
StarCraft: Brood War
ggaemo 325
actioN 175
Hyuk 172
PianO 164
Shuttle 67
Hm[arnc] 49
ZergMaN 35
yabsab 28
Shinee 23
GoRush 22
[ Show more ]
910 19
Yoon 12
Noble 9
Free 9
Nal_rA 8
Bale 7
soO 4
Dota 2
febbydoto59
League of Legends
JimRising 763
C9.Mang0364
Super Smash Bros
Mew2King118
Other Games
summit1g12060
WinterStarcraft501
Sick0
Organizations
Other Games
gamesdonequick1189
StarCraft 2
Blizzard YouTube
StarCraft: Brood War
BSLTrovo
sctven
[ Show 12 non-featured ]
StarCraft 2
• AfreecaTV YouTube
• intothetv
• Kozan
• IndyKCrew
• LaughNgamezSOOP
• Migwel
• sooper7s
StarCraft: Brood War
• BSLYoutube
• STPLYoutube
• ZZZeroYoutube
League of Legends
• Lourlo1268
Other Games
• Shiphtur335
Upcoming Events
RongYI Cup
3h 56m
herO vs ShoWTimE
Solar vs Classic
Wardi Open
6h 56m
Monday Night Weeklies
9h 56m
OSC
16h 56m
Replay Cast
1d 1h
RongYI Cup
1d 3h
Clem vs TriGGeR
Maru vs Creator
WardiTV Invitational
1d 6h
Replay Cast
2 days
RongYI Cup
2 days
WardiTV Invitational
2 days
[ Show More ]
The PondCast
3 days
HomeStory Cup
4 days
Korean StarCraft League
4 days
HomeStory Cup
5 days
Replay Cast
5 days
HomeStory Cup
6 days
Replay Cast
6 days
Liquipedia Results

Completed

BSL 21 Non-Korean Championship
OSC Championship Season 13
Underdog Cup #3

Ongoing

CSL 2025 WINTER (S19)
KCM Race Survival 2026 Season 1
Acropolis #4 - TS4
Rongyi Cup S3
BLAST Bounty Winter 2026
BLAST Bounty Winter Qual
eXTREMESLAND 2025
SL Budapest Major 2025
ESL Impact League Season 8
BLAST Rivals Fall 2025

Upcoming

Escore Tournament S1: W6
Escore Tournament S1: W7
Acropolis #4
IPSL Spring 2026
uThermal 2v2 2026 Main Event
Bellum Gens Elite Stara Zagora 2026
HSC XXVIII
Nations Cup 2026
PGL Bucharest 2026
Stake Ranked Episode 1
BLAST Open Spring 2026
ESL Pro League Season 23
ESL Pro League Season 23
PGL Cluj-Napoca 2026
IEM Kraków 2026
TLPD

1. ByuN
2. TY
3. Dark
4. Solar
5. Stats
6. Nerchio
7. sOs
8. soO
9. INnoVation
10. Elazer
1. Rain
2. Flash
3. EffOrt
4. Last
5. Bisu
6. Soulkey
7. Mini
8. Sharp
Sidebar Settings...

Advertising | Privacy Policy | Terms Of Use | Contact Us

Original banner artwork: Jim Warren
The contents of this webpage are copyright © 2026 TLnet. All Rights Reserved.