• Log InLog In
  • Register
Liquid`
Team Liquid Liquipedia
EDT 14:02
CET 19:02
KST 03:02
  • 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
[ASL22] Finals Preview: Sweet Victory!9[ASL22] Ro4 Preview: Mirror Mirror6[ASL22] Ro8 Preview: Within Reach5[ASL22] Ro8 Preview: In A Tizzy11[ASL22] Ro16 Preview: Holy Diver5
Community News
Evil Geniuses - shutting down14ISSL (IntoTheTV x SOOP SC2 League): Premier5Weekly Cups (October 12-18): 5.0.17 era begins1[$1250] International ShieldBattery League73Weekly Cups (October 5-11): Farewell to 5.0.167
StarCraft 2
General
How do you feel about the mass reverts in the 5.0.17 PTR? REPORT: StarCraft 2: Remastered In Development Team Liquid Map Contest #22: Results and Winners No more SC2 streamers on team liquid? Evil Geniuses - shutting down
Tourneys
ScienceCraft (October 24-25) - Live Event Sparkling Tuna Cup - Weekly Open Tournament RSL goes to London! 2026 Offline Finals Nov 21-22 ISSL (IntoTheTV x SOOP SC2 League): Premier WORTEX Challenger Series — Open SC2 LAN in Budapes
Strategy
[H] ZvP Mid-Late Game: Stalkers Collossi HT
Custom Maps
[G] How to playtest arcade maps [A] Nemrods 1/4 players [M] (2) Sweltering Sands
External Content
Mutation # 549 Endless Sparkles The PondCast: SC2 News & Results Mutation # 548 Shining Bright Mutation # 547 Temple Of Terror
Brood War
General
Bot on ladder BW General Discussion Recent recommended BW games Oceanic Brood War - Join and chat! Sagi.gg Launcher Released
Tourneys
[ASL22] Grand Finals [$1250] International ShieldBattery League [BSL23] RO24 Group C Small VOD Thread 2.0
Strategy
Cliff Jump Revisited (1 in a 1000 strategy) 50,000-Word Terran Builds Memo 2026-10-22 Simple Questions, Simple Answers
Other Games
General Games
Stormgate/Frost Giant Megathread Nintendo Switch Thread Mobile Legends: Bang Bang Armies of Exigo - YesYes? General RTS Discussion Thread
Dota 2
Dota 2 Champions League Season 3 Begins April 25!
League of Legends
[TL LoL EUW IHs] Teemo shall perish
Heroes of the Storm
Heroes of the Storm 2.0
Hearthstone
Deck construction bug
TL Mafia
TL Mafia Community Thread
Community
General
US Politics Mega-thread Things Aren’t Peaceful in Palestine European Politico-economics QA Mega-thread Russo-Ukrainian War Thread Canadian Politics Mega-thread
Fan Clubs
Reynor Fan Club The Flash Fan Club Serral Fan Club
Media & Entertainment
Anime Discussion Thread Movie Discussion! [Manga] One Piece
Sports
Football (Soccer) Thread TeamLiquid Health and Fitness Initiative For 2023 MLB/Baseball 2023
World Cup 2022
Tech Support
Computer Build, Upgrade & Buying Resource Thread
TL Community
Recent Gifted Posts
Blogs
Innovate or Game Over?
TrAiDoS
ShieldBattery on Mac
Kraekkling
[ASL22] Ro4 Day1 Ticket Giv…
bITt.mAN
Can Bots Beat Pros?? Starcr…
namkraft
Customize Sidebar...

Website Feedback

Closed Threads



Active: 11170 users

PHP - Date Format Check

Blogs > tofucake
Post a Reply
1 2 Next All
tofucake
Profile Blog Joined October 2009
Hyrule19264 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
Hyrule19264 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
Hyrule19264 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
Netherlands10343 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
Hyrule19264 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
Hyrule19264 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
Hyrule19264 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
Singapore66366 Posts
July 23 2010 14:43 GMT
#17
php looks hard ;;
POGGERS
tofucake
Profile Blog Joined October 2009
Hyrule19264 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
Hyrule19264 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
Next event in 16h 59m
[ Submit Event ]
Live Streams
Refresh
StarCraft 2
UpATreeSC 131
MindelVK 21
StarCraft: Brood War
Calm 2676
Shuttle 496
EffOrt 353
actioN 283
Dewaltoss 163
Soulkey 115
Mind 78
ProTech76
Zeus 69
Barracks 40
[ Show more ]
Trap 27
ToSsGirL 21
Aegong 20
Hm[arnc] 15
Killer 15
Shine 12
Sacsri 8
Dota 2
Gorgc14128
qojqva2205
BananaSlamJamma194
Fuzer 151
League of Legends
Reynor52
Counter-Strike
pashabiceps817
Heroes of the Storm
Khaldor267
Trikslyr140
Other Games
Liquid`RaSZi2054
singsing1680
Beastyqt766
FrodaN623
ToD245
RotterdaM133
XaKoH 128
QueenE35
Chillindude11
ZombieGrub1
Organizations
Counter-Strike
PGL37179
[ Show 18 non-featured ]
StarCraft 2
• Reevou 8
• AfreecaTV YouTube
• intothetv
• Kozan
• IndyKCrew
• Migwel
StarCraft: Brood War
• HerbMon 32
• Michael_bg 7
• Pr0nogo 3
• BSLYoutube
• STPLYoutube
• ZZZeroYoutube
League of Legends
• Nemesis2892
• Jankos2651
• Scarra773
• TFBlade465
Other Games
• Shiphtur558
• imaqtpie550
Upcoming Events
IntoTheTV X SOOP
16h 59m
ByuN vs Lambo
MaxPax vs Bunny
PiGosaur Cup
1d 5h
The PondCast
1d 15h
Kung Fu Cup
1d 16h
IntoTheTV X SOOP
2 days
SHIN vs GuMiho
Clem vs Classic
OSC
3 days
WardiTV Invitational
3 days
GSL
3 days
Epic.LAN
3 days
Replay Cast
4 days
[ Show More ]
Sparkling Tuna Cup
4 days
Epic.LAN
4 days
Yamato Cup
5 days
Map Test Tournament
6 days
WardiTV Weekly
6 days
Liquipedia Results

Completed

Acropolis #5 - GSC
Blizzard Classic Cup 2026
HCC Season 3

Ongoing

Acropolis #5
KCM Race Survival 2026 Season 4
ShieldBattery League 1
BSL Season 23
PGL Masters Bucharest 2026
1win Private Club #2
Thunderpick World Champ. '26
ESL Pro League Season 24
Stake Ranked Episode 4
1win Private Club #1
Logitech G Play Connect 2026
SL StarSeries Fall 2026
FISSURE Playground #3
BLAST Open Fall 2026
Esports World Cup 2026

Upcoming

IPSL Winter 2026-27
SC4ALL II: Brood War
BSL 23: Non-Korean Championship
HSC XXX
Stellar Fest 2: Lunar Cup
SC4ALL II: StarCraft II
Kung Fu Cup 2026 Grand Finals
RSL Offline Finals
eXTREMESLAND 2026
PGL Major Singapore 2026
Stake Ranked Episode 6
BLAST Rivals Fall 2026
IEM Beijing 2026
Stake Ranked Episode 5
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.