List dates in months from database - php

Hey, I need som help to list my added dates from database, and split it into their added month.
I have no clue on how to do it... Soe can someone please show me examples, or maybe some tutorials how to do?
Thx

Something along the lines of this, perhaps?
SELECT * FROM table GROUP BY MONTH(dateColumn)
SELECT * FROM table WHERE MONTH(dateColumn) = 9

A must-read reference for date & time handling functions in MySQL is:
http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html

Are you looking for the MySQL MONTH() Function?
Query: SELECT MONTH(NOW());
Output: 11

Not entirely sure what you mean but here goes...
The sample below creates a test collection (assumably your collection retrieved from the database) and groups them by Month and Year and then displays the result. It uses Linq and anonymous objects which you could easily replace with some POCO classes...
Sub Main()
Dim ls As New List(Of Object)
Dim lsGroup As New List(Of Object)
Dim ran As New Random(Now.Millisecond)
'' build a sample collection
For x As Integer = 1 To 100
ls.Add(New With {.ID = x, .DateAdded = Now.AddMinutes(-(ran.Next(1, 100000)))})
Next
'' now group them into years and months
For Each item In ls
Dim currentItem As Object = lsGroup.Where(Function(o) o.Year = item.DateAdded.Year And o.Month = item.DateAdded.Month).SingleOrDefault()
If currentItem Is Nothing Then
'' create
Dim var = New With {.Year = item.DateAdded.Year, .Month = item.DateAdded.Month, .ItemCollection = New List(Of Object)}
var.ItemCollection.Add(item)
lsGroup.Add(var)
Else
'' add
currentItem.ItemCollection.Add(item)
End If
Next
'' display the results
For Each group In lsGroup
Console.WriteLine(group.Year & " - " & MonthName(group.Month))
For Each item In group.ItemCollection
Console.WriteLine(" > " & item.ID & " - " & item.DateAdded.ToString())
Next
Console.WriteLine()
Next
Console.ReadLine()
End Sub

Here's what I do when I need the month that's in a timestamp or date item called "t".
TIMESTAMP(DATE_FORMAT(t,'%y-%m-01'))
This returns another timestamp that represents midnight on the first day of that month.
Works for weeks too.
TIMESTAMP(FROM_DAYS(TO_DAYS(t) -MOD(TO_DAYS(t) -1, 7)))
This obscure incantation returns a timestamp that represents midnight on the Sunday preceding the given timestamp.

Related

PHP MySql time calculations

I want to calculate how much time the worker has left since break start.
By the click, PHP insert into history table a record with timestamp (break_start), after second click, PHP update record with timestamp (break_end).
Now i can calculate time difference using this code:
$break_start = $worker->query('SELECT break_start FROM history WHERE id = 16')->fetchArray();
$break_end = $worker->query('SELECT break_end FROM history WHERE id = 16')->fetchArray();
$diff = $worker->query("SELECT TIMEDIFF('".$break_end['break_end']."','".$break_start['break_start']."') AS total")->fetchArray();
$break_total = $worker->query("SELECT break_time FROM worker WHERE id = 7")->fetchArray();
echo $diff['total']." ";
echo $break_total['break_time']." ";
$str1 = strtotime($diff['total']);
$str2 = strtotime($break_total['break_time']);
Output is: 00:31:26 00:30:00.00 86 01:26
(This code above is just attempt to understand time in PHP and MySQL).
I want to subtract break time from "break" value which is stored in table "worker" (default value is 30).
I don`t know how to do this..

Is it bad to use a middle sql table

I have a db-table that holds holidays i.e. when Cristmas, Easter different fasts UN-days and also celebrations from the Hijri (Muslim), Hebrew (Jewish) and Chineese calendars.
All holidays are saved on the date(s) they occur in their own calendar. But not all days are celebrated on a particular date. An example is the four Advent sundays which for the fourth one is between the dates of 18:th and 24:th of december and on a sunday.
There are also other examles as in the Netherlands where some days of celebration are moved when on a Sunday.
When it comes to fasts they can hav varied length and at least in the Swedish protestant church there are also Sunday masses wich are excluded if a more important one occurs.
So my table is set up as follows:
The PHP for the actual SQL, note that it itterates over all calendars.
foreach ($kal as $kalender => $arr_date) {
$go_Y = (int)$arr_date['go']['Y'];
$go_m = (int)$arr_date['go']['m'];
$go_d = (int)$arr_date['go']['d'];
$end_Y = (int)$arr_date['end']['Y'];
$end_m = (int)$arr_date['end']['m'];
$end_d = (int)$arr_date['end']['d'];
$sql = "SELECT
id,
name,
IF (picture_link = '', type_image, picture_link) AS logo,
start_year,
start_month,
start_day,
end_year,
end_month,
end_day,
year_interval,
start_weekday,
shift,
period,
ends_with_holiday,
has_php,
is_type,
in_calendar,
begins_year,
first_year,
bank_holiday,
has_note,
source_link,
COUNT(flagday_id) AS flagdays,
flagday_for_contry, /* if for only one contry, othervise an extra SQL is needed */
flagday_type,
flagday_information,
flagday_source
FROM holiday
LEFT JOIN type ON (type.id = holiday.is_type)
LEFT JOIN flagday ON (holiday.id = flagday_for_holiday)
WHERE is_calendar = $kalender
AND (start_year IS NULL OR start_year <= $end_Y)
AND (end_year IS NULL OR end_year >= $go_Y)
AND IF($end_m < $go_m OR ($end_m = $go_m AND $end_d < $go_d), /* If over new years */
(start_month < $end_m OR start_month = $end_m AND start_day <= $end_d)
OR (end_month > $go_m OR end_month = $go_m AND end_day >= $go_d)
, /* ELSE, if not over new years */
(start_month < $end_m OR start_month = $end_m AND start_day <= $end_d)
AND (end_month > $go_m OR end_month = $go_m AND end_day >= $go_d)
)
GROUP BY id
ORDER BY start_weekday IS NULL DESC,
start_weekday DESC";
$result = mysqli_query($con, $sql) or die(mysqli_error($con));
while ($result && mysqli_num_rows($result) && $row = mysqli_fetch_array($result)) {
if($kalender == 8) { // om den cyclic jewish calendar, one more argument is needed
$out_arr = get_holiday ($ut_arr, $row, $kalender, $go_Y, $go_m, $go_d, $end_Y, $end_m, $end_d, $con, $country, array($kal[4]['go']['Y']));
} else {
$out_arr = get_holiday ($ut_arr, $row, $kalender, $go_Y, $go_m, $go_d, $end_Y, $end_m, $end_d, $con, $country);
}
}
The get_holday() function does the PHP part if 'has_php' = 1 and also adds roman numerals to the end if a holiday is more than one day. But in essence it just puts the row in an multidimensional array: The first part is the gregorian date when it occurs (there are two helperfunctions to convert dates), the second is just an irreation on that Gregorian date and the third is the different columns from the db.
$out_arr['Y-m-d'][$i][$column] = $column_value;
So now the question
This as you can see is cuite time consuming an for now it's only been for personal use so it hasn't been a real problem. If you want an examle (in Swedish) the top left part with the picture icons on my links page
I was instead thinking of outputting all this into an other db table that just holds the id and (Gregorian) date (for the next 10 years) and each year or when a new holiday is added just update the new table. Is this a good idea or does it just create the same data in multiple places and a risk that they don't match in the end?
Use foreign key constraints to make sure your database stays consistent:
Have one table with all days in it,
one for the various kinds of holiday days,
one for the various countries' calendars,
and one mapping table that says which days are what kind of day in what regional calendar.
And then pre-calculate everything. This method is flexible and allows for unlimited calendars/countries/holidays, and you can expand with more metadata about each kind of holiday and so on either by adding it into separate tables, or adjusting only the affected table. This is easier to maintain.

Date insertion in Cassandra DB: non-trivial 1h shift issue

I am a bit desperate about this problem... I have no idea how to face it.
Here is a simpler way to look at this problem:
If my insert cql query is:
"BEGIN BATCH USING CONSISTENCY ONE insert into my_table(id,'2014-04-11 8:00:00',...,'2014-04-15 10:00:00') values ('2036548',3.15,...,4.11) APPLY BATCH"
...and my data request cql query is:
"Select FIRST 100000 '2014-04-01 0:00:00'..'2014-04-16 0:00:00' from my_table where id=2036548"
...why does the inserted date 2014-04-15 10:00:00 changes to 2014-04-15 11:00:00 when pullling it from Cassandra?
The date pulling code in vb.net is:
Public Shared Function getCassandraDate(ByVal value As Byte()) As Date
Dim buffer As Byte() = New Byte(value.Length - 1) {}
value.CopyTo(buffer, 0)
Array.Reverse(buffer)
Dim ticks As Long = BitConverter.ToInt64(buffer, 0)
Dim dateTime As New System.DateTime(1970, 1, 1, 0, 0, 0, _
0)
dateTime = dateTime.AddMilliseconds(ticks)
Return dateTime.ToLocalTime
End Function
...same thing in PHP:
date_default_timezone_set("Europe/Paris");
$time = $this->unpackDate($packed_time);
$str_time = date('Y-m-d H:i:s',$time); //TODO : to local time
private function unpackDate($data, $is_name=null)
{
$arr = unpack('N2', $data);
// If we are on a 32bit architecture we have to explicitly deal with
// 64-bit twos-complement arithmetic since PHP wants to treat all ints
// as signed and any int over 2^31 - 1 as a float
if (PHP_INT_SIZE == 4) {
$hi = $arr[1];
$lo = $arr[2];
$isNeg = $hi < 0;
// Check for a negative
if ($isNeg) {
$hi = ~$hi & (int)0xffffffff;
$lo = ~$lo & (int)0xffffffff;
if ($lo == (int)0xffffffff) {
$hi++;
$lo = 0;
} else {
$lo++;
}
}
// Force 32bit words in excess of 2G to pe positive - we deal wigh sign
// explicitly below
if ($hi & (int)0x80000000) {
$hi &= (int)0x7fffffff;
$hi += 0x80000000;
}
if ($lo & (int)0x80000000) {
$lo &= (int)0x7fffffff;
$lo += 0x80000000;
}
$value = $hi * 4294967296 + $lo;
if ($isNeg)
$value = 0 - $value;
} else {
// Upcast negatives in LSB bit
if ($arr[2] & 0x80000000)
$arr[2] = $arr[2] & 0xffffffff;
// Check for a negative
if ($arr[1] & 0x80000000) {
$arr[1] = $arr[1] & 0xffffffff;
$arr[1] = $arr[1] ^ 0xffffffff;
$arr[2] = $arr[2] ^ 0xffffffff;
$value = 0 - $arr[1]*4294967296 - $arr[2] - 1;
} else {
$value = $arr[1]*4294967296 + $arr[2];
}
}
return $value / 1e3;
}
MORE DETAILS
Processing chain:
(1). insertion to Cassandra through .NET
(2). Cassandra data storage
(3). Pulling the data from PHP or .NET
Problem:
As for today, a date being 2014-04-15 10:00:00 in step (1), will come out as 2014-04-15 11:00:00 in step (3).
Details:
(regarding the date format in this chain)
(1). Local time in .NET (Timezone: "Europe/Paris"). Insertion cql that is being executed: "BEGIN BATCH USING CONSISTENCY ONE insert into my_table(id,'2014-04-11 8:00:00',...,'2014-04-15 10:00:00') values ('2036548',3.15,...,4.11) APPLY BATCH"
(2). ??? I don't know what Cassandra does here... ???
(3). Example of cql query to pull the data: "Select FIRST 100000 '2014-04-01 0:00:00'..'2014-04-16 0:00:00' from my_table where id=2036548". In php: date_default_timezone_set("Europe/Paris"); $str_time = date('Y-m-d H:i:s',$time);. In .NET: dateTime.ToLocalTime.
Extra info:
I think it worked well before the daylight saving time change some weeks ago. But I can not be sure about that.
If in step (1), if I changed the date to de date to UTC before inserting it, 2014-04-15 10:00:00 will become 2014-04-15 08:00:00 and the output will be 2014-04-15 09:00:00, which is still not correct.
I highly suspect that the trick here is between steps (1) and (2), that is to say, me not being able to understand how Cassandra treats dates.
Edit1:
#Ananth 's questions:
both cassandra and client run in the same datacenter?
It is complicated:
Insertion in .NET from server1, a different server from server-cassandra (datacenter).
PHP (to pull the data) running on server-cassandra.
.NET (to pull the data) running on server1, not on server-cassandra.
PHP and .NET pulling the same result.
Can you post your schema here?
Here it is
CREATE TABLE tsmeasures (
id int PRIMARY KEY
) WITH
comment='' AND
comparator=timestamp AND
read_repair_chance=0.100000 AND
gc_grace_seconds=0 AND
default_validation=double AND
min_compaction_threshold=4 AND
max_compaction_threshold=32 AND
replicate_on_write='true' AND
compaction_strategy_class='SizeTieredCompactionStrategy' AND
compression_parameters:sstable_compression='SnappyCompressor';
Edit2:
After testing it step by step, this is the result:
real date : 2014-04-15 17:00:00 (localtime)
cql text : '2014-04-15 15:00:00' (to UTC, done through .NET)
PHP Cassandra Unpack of this date => $ticks = 1397577600 (*) The unpack is done with the piece of code shown before
Ticks converted (through http://www.epochconverter.com/ )
GMT: Tue,
15 Apr 2014 16:00:00 GMT Your time zone: 4/15/2014 6:00:00 PM GMT+2
These results makes no sense to me...
More details:
cql insert:
"BEGIN BATCH USING CONSISTENCY ONE insert into tsmeasures(id,'2014-04-11 15:00:00',...,'2014-04-15 15:00:00') values ('2036548',0,...,4.85) APPLY BATCH"
cql fetch:
"SELECT '2014-04-10 16:00:00'..'2014-04-20 17:00:00' FROM tsmeasures WHERE id IN
(2036548,2036479,2036174,650877)"
Thus '2014-04-15 15:00:00' is included in the range of the fetch, and I can identify it because it is the highest value.
I will keep digging...
This seems to be a time zone issue. It appears you are neither specifying a timezone when storing nor when retrieving the timestamps. According to the documentation Cassandra applies the timezone of the coordinator node handling the write request if no timezone is supplied by the client. If timestamps shift between writing and reading them, that probably means all or some of your Cassandra nodes are not configured for the same timezone as your client is.
Before Edit
Is there a clock time sync problem between your client and cassandra? I would strictly recommend running NTP between your client and cassandra installation.
Post Edit
CREATE TABLE tsmeasures (
id int PRIMARY KEY
) WITH
comment='' AND
comparator=timestamp AND
read_repair_chance=0.100000 AND
gc_grace_seconds=0 AND
default_validation=double AND
min_compaction_threshold=4 AND
max_compaction_threshold=32 AND
replicate_on_write='true' AND
compaction_strategy_class='SizeTieredCompactionStrategy' AND
compression_parameters:sstable_compression='SnappyCompressor';
From what you have given , it looks like you are trying to get the insertion time .
Your problem might be due to clients running in different clock cycles with respect to cassandra. Cassandra just places a unix timestamp for each write.
So what is happening here from what i see.
You write from client using timestamp X(datastax driver sets this insertion timestamp). Cassandra writes with X.
You read with a timestamp Y. Cassandra tries to read with timestamp Y(So , as per your explanation, PHP client is there in a different location).
Both a are bound to differ.
Solution 1
Try to have a global NTP between the entire set up so that client clock cycles are in sync with cassandra.
Solution 2
Insert a column named timestamp which is user driven and do a range scan based on that
Solution 3
Set the insertion time in DML operations.

how to delete firstdigit 0 from date and month

Code:
$today_mem = date("d.m");
echo $today_mem; // -> 15.02
I need to transform dates like 15.02 into 15.2, also need to transform for ex. 07.02 into 7.2 and so on every day.
So the question is: how to delete firstdigit 0 from date and month.
Any short solutions?
You'll want to use:
$today_mem = date("j.n");
echo $today_mem; // -> 15.2
To remove the leading zeros. See more format modifiers at: php.net/date
Use j instead of d and n instead of m:
$today_mem = date("j.n");
Reference at the PHP doc site.
use
$today_mem = date("j")

How to efficiently filter datetime column for extracting data?

I am usng sqlite to log data every 5 minutes to a column that is time stamped with and integer in Unix time. The user interface uses php code to extract data in various user selectable time frames which is then plotted using javascript. Charts typically have 12 data/time points and I need to extract data for plotting over different periods of say 1Hr/12Hr/24Hr/12days/month/year. So only need to extract 12 data rows per search. So for a 24Hr plot I need to only extract data at houly intervals (when minutes = 0) similarly for 12day plots at daily intervals (when mins=0 && hours=0) etc.
My php code for 1Hr works fine since the data is logged every 5min giving me 12 rows of data between search start time and end time. What is an efficient way of extracting data for the longer periods when number of rows between start time and end time is greater than 12? I need to further filter the search to efficiently extract only the data I need?
any suggestions - most appreciated - frank
$db = new MyDB(); // open database
$t=time(); // get current time
$q1 = "SELECT TimeStamp,myData FROM mdata WHERE ";
$q2 = " AND TimeStamp <=".$t; // end time
$q3 = " AND TimeStamp >=".($t-3600); // start time 1 hour earlier
$qer = $q1.$q2.$q3; // my search query form above parts
$result = $db->query($qer);
$json = array();
while ($data = $result->fetchArray(SQLITE_NUM)) {
$json[] = $data;
}
echo json_encode($json); // data is returned as json array
$db->close(); // close database connection
I think you should use WHERE date BETWEEN in your search query?
This kind of search could take up a lot of time once data builds up?
Since you already know the exact times you're interested in, you should probably just build an array of times and use SQL's IN operator:
$db = new MyDB(); // open database
$timeStep = 300; // Time step to use, 5 minutes here - this would be 3600 for hourly data
$t = time(); // get current time
$t -= $t % $timeStep; // round to the proper interval
$query = "SELECT TimeStamp,myData FROM mdata ";
$query .= "WHERE TimeStamp IN "
$query .= "(" . implode(",", range($t, $t + $timeStep * 12, $timeStep)) . ")";
$result = $db->query($query);
$json = array();
while ($data = $result->fetchArray(SQLITE_NUM)) {
$json[] = $data;
}
You'll need to do some different math for monthly data - try constructing 12 times with PHP's mktime() function.
Here are the references for the PHP implode() and range() functions I used.

Categories