I need to compare Bikram Sambat dates in PHP. Lets say today in AD is 2012-08-03, the BS date today is 2069-04-19. In BS, we have total number of days in a month ranging from 29 to 32. Again, the days are not consistent in every year. Example if this year current month have 31 days, next year same month might have 30 or even 32 days.
The way i could think is, using a php date converter class (which I already have), convert given BS Dates to equivalent AD Dates and compare them. Just i want to know is there any other better way to do this without using the class i have??
By saying comparing here I mean
a) Finding days between the given date ranges.
b) Checking whether a date lies on a given two date ranges
c) And other comparisons we could do with AD dates using php Date Function
thanks any help is highly appreciated.
Generally, I would suggest converting both dates to unix timestamps (seconds since 1970-1-1 AD) which is a simple integer value for comparison.
Apparently, there is no simple logic behind BS so you will not be able to find an analytic expression that directly gets you from here to there. If you do not wish to use an external class you could write some sort of (recursive) function that starts from 1970-1-1 AD which you manually convert to BS and counts up the timestamp from there following the rules for BS.
Have a look at the source code of KashmirStamps.ca/Samvat.html
It is converting BS Dates to AD dates. You will find Javascript Code & Logic. You can easily adapt the logic to PHP code.
Related
I am posting this optimistically after searching for an answer here on SO, and even when SO tells me my question might be closed, as I think in this case it's a valid question.
Consider a CSV file with a column containing string representing either dates, or times, or both. I want to find out after reviewing the column, just that - exactly what type of column is it, not just that it's a valid "date"?
PHP function strtotime does an amazing job of returning a unix timestamp for pretty much any date-time-ish string. But (today when I'm posting this on 10/8/2018), 3:45PM and 15:45:00 and 10/8/2018 3:45PM would all return the same unix time, though obviously the first two are times.
What is a method to determine if a string is strictly a date component, a time component, or both?
P.S. If I have to write a function myself, so far the best lead would be to look for a : in the string, which would mean there's a time component (meaning either time, or datetime). If it parses as a datetime, but with no : present, then we could assume it's a date only. But again, I am wondering if PHP has a more elegant way. Here is a "pretty good" solution:
P.P.S this function is actually a "very good" solution now thanks to #KarstenKoop's clever suggestion in comments about the 2nd parameter for strtotime:
function date_time_component($date){
if(strtotime($date) === false) return false;
if(strtotime($date, 86400) !== strtotime($date, 86400 * 2)) return 'time';
if(strstr($date, ':')) return 'datetime';
return 'date';
}
You should start by writing a set of test cases - which you could have included in your question. There are lots of different ways to write dates and a few ways to write times.
Here's some to get you started:
dates
2018-10-08
08/10/2018
10/08/2018
08-10-2018
10-08-2018
10-Oct-2018
20181008
10 Oct 2018
10th October 2018
October, 10th 2018
times
1121
11:21
11:21 AM
11:21
11:21:46
11:21:46 AM
Timezones
+00:00
+0
+0000
Europe/London
Then you have all the possible combinations of the 3 components:
date
date time
date time timezone
time
time timezone
time date
time timezone date
That gives 400 different formats (not all of which are uniquely resolvable).
(using strtotime to do the heavy lifting starts making a lot of sense). But rather than trying to parse the data, looking for specific patterns might be a better approach: are there strings of letters? a + or -? How many digits? How many consecutive digits?
You should still be starting with a list of test cases.
I wonder know how to deal data format. I have 2 columns date(starting date) *date2 (end date)*. I am not familiar with php/mysql.
one my biggest clue is the data/data2 fields appears on this format ie. "1394797440". I am trying to build a dashboard with DB graphics of a ticket support. Had some features done but the data format is stressing me up. let me know if I am right.
I need to do a foreach on both fields? sorry my noob question but I am totally lost :|
mostly I use this call-> $call_date = date("m/d/y",$site_calls->call_date);
I will really appreciate any help.
This is a UNIX epoch datetime format i.e. number of seconds elapsed since 1st Jan, 1970. To take average of the two dates, it is similar to any other numeric average.
$avg_date = $site_calls->call_date + (($site_calls->call_date2 - $site_calls->call_date)/2);
$call_date = date("m/d/y",$avg_date);
The data/data2 format is most likely Unix epoch time. It is the number of seconds since Jan 1, 1970 and can be converted to an actual date and time.
I saw in PHP's documentation that there are two ways to format the year value in 4 digits:
Y - A full numeric representation of a year, 4 digits
o - ISO-8601 year number. This has the same value as Y, except that if the ISO week number (W) belongs to the previous or next year, that year is used instead. (added in PHP 5.1.0)
I researched more what the ISO-8601 is and it seems to be more "useful" or even accurate(?) based on php's documentation. I think it's more useful because it prevents ambiguity (like when handling date values like 1981-04-05).
But does it really make a difference? Is there some sort of "best practice"? Is 'o' slower that's why people use Y instead when they're not really doing anything complicated with the dates?
What specific use-cases perhaps is this useful?
Thank you for your help.
EDIT:
Thank you Jason for an example! I guess why I brought this up as well is I'm wondering why not just use 'o' all the time? I'm thinking I should just use 'o' all the time for currently unknown future specification that will require me to do more complex date operations.
o would be used when trying to determine the year of the current week (i.e. calendar week).
Y would be used for output of the year for a specific date.
This is shown by the following code snippet:
date('Y v. o', strtotime('2012-12-31')); // output: 2012 v. 2013
Not saying it makes it best-practice, but Y is more commonly used to output year. As noted, o would be incorrect/confusing to output the year for such boundary dates.
ISO 8601 is a very useful standard for representing dates, but it has several components, not all of which are useful for many purposes. In particular, the "ISO week" and "ISO year" can be slightly confusing terms, and they're often not what you really want to use (and if you do want to use them, you probably already know that).
Wikipedia has a pretty good explanation. Basically, the ISO 8601 standard defines a separate calendar that, instead of breaking up into months and days of the month, breaks up into weeks and days of the week.
You might think this wouldn't make a difference for specifying the year, but there's a little wrinkle: which year do the weeks near the beginning and end of the calendar year fit into? As Wikipedia says, it's not quite intuitive: "The first week of a [ISO] year is the week that contains the first Thursday of the [calendar] year."
The practical upshot: If you're representing dates as conventional year-month-day values, you don't want to use the "ISO year" (o). You won't notice the difference for most of the year, but as you get to December and January, suddenly you'll (sometimes) end up with dates that are a year off. If you just test your system with current dates, you can easily miss this.
Instead, you probably just want to be using plain old Y-m-d. Even though the date() documentation doesn't specifically say it, that's a perfectly valid ISO 8601 standard date.
Really, you should only be using o if you're using the ISO "week date" calendar (meaning you're likely also using W for the week number and N for the day-of-week).
I'm creating a report in php in which 6 html drop downs appear and prompt the user to enter the two dates in which they would like to see the data of the report. So for example the report goes as follows:
See data between: [month][day][year] and [month][day][year] (where the brackets signify a select tag)
Also in this report is a function which calculates the percentage increase or decrease from the previous day. So for example if the user does not select any date range, it's simply data of the current day and the percentage is calculated as:
round(((($newDataPointCount - $yesterdayDataPointCount) / $yesterdayDataPointCount) * 100),2)
This is obviously very easy to calculate for only one day because I can tell it to query the SQL database with INTERVAL 1 DAY. But here is my question, how would I calculate the number of day intervals if the months change?
Everything would work great if the user stays within one month so it would be something like [March][20][2012] - [March][29][2012], and I can easily calculate the value is 9, but when it's something like [February][27][2012] - [March][20][2012], how can I calculate the number of days in between?
Just to clarify any questions that may arise, I'm using PHP and MySQL and would prefer to stay within those bounds.
The MySQL DATEDIFF function should accomplish the task
DATEDIFF
Dates are not scalars and should not be treated as such. My advice is to user the proper tools for date arithmetic.
A lot of people suggest unix timestamp oriented date math:
$a = '2012-02-12 14:03:50';
$b = '2012-05-30 00:55:03';
$days = (strtotime($b) - strtotime($a))/86400;
However, daylight saving time and all of kinds of factors can make that type of math wrong.
My approach is to typically use DateTime:
$a = new DateTime('2012-02-12 14:03:50');
$b = new DateTime('2012-05-30 00:55:03');
$diff = $b->diff($a);
//$diff is now a DateInterval
However, to answer your real question, I would not pull the data from MySQL based on MySQL date math, but rather I would just give it dates.
WHERE d >= '2012-02-27' AND d <= '2012-03-29';
Though based on your requirements, you may need to alter the 27 to 26 as to grab the previous day and do the calculations with it.
As for doing the changes in point values, I would either precalculate and store them, or I would just calculate them in PHP. There's no simple way to tell SQL "hey grab every record between these dates and while you're at it, do some math with each record's previous record."
I hope this has been clear, but I have a feeling it borders on rambling other than clarity, so if so, please let me know and I'll edit my answer.
I have a table with 2 rows, one of which represents date and the other time. These rows are not date format; they are int type and I can't change the original rows' type. The date entries are written as 20120306, and the time entries are written, for example, 13000 for 01:30 UTC in 5 digits, and 130000 for 13:00 UTC in 6. What I need to do is put both strings (date and time) into 1 UNIX timestamp. I can either use this in a php script or merge them into a new table, whichever works best. The problem for me is the php mysql syntax, functions and sequence for putting these 2 odd strings together into one timestamp.
If I can figure out how to do this, it would help me solve a whole mess of inaccuracies in a calendar reminder script I am trying to put together. I have tried configuring these strings into times separately in the queries, but no matter how it's filtered, the outcome is right in some circumstances and wrong in others due to the nature of the original program. If I had a PHD in PHP I would rewrite the entire program but I don't. I am a major newbie at this. So I just need to write my little PHP scripts to utilise what has already been provided. Any help in my learning quest would be appreciated.
The function strtotime() can also read compound formats.
If you take a look at that list you will notice that your format is a close match to the "XMLRPC (Compact)" listed there.
It's your date string concatenated with a "t" and the time string. So, after you expanded your time string to length 6 (you already know how to do that), you can produce such a string and strtotime() will output your Unix time stamp:
$dt = "20120306";
$tm = "130000";
$unixTime = strtotime($dt . "t" . $tm);