Doctrine's date field - how to write query - date

I'm using Symfony2 and Doctrine.
I have a date field, here it is:
/**
* #ORM\Column(type="date")
*/
protected $date;
In my form I use a text field to avoid Chrome default datepicker, but I insert DateTime objects in the database:
if ($request->isMethod('POST')) {
$form->bind($request);
//Convert string date to DateTime object and send it to database as object
$dateObj = \DateTime::createfromformat('d-m-Y', $expense->getDate());
$expense->setDate($dateObj);
// ...
and then I want to find all items with a specific date:
public function findExpensesForDate($user, $date)
{
$q = $this
->createQueryBuilder('e')
->where('e.date = :date')
->andWhere('e.user = :user')
->setParameter('date', $date)
->setParameter('user', $user)
->getQuery();
return $q->getResult();
}
and call it like this:
$expenses_for_today = $this->repository->findExpensesForDate($this->user, $today);
which returns nothing when
$today = new /DateTime();
and returns the results when
$today_obj = new /DateTime();
$today = $today_obj->format('Y-m-d');
So why when I give the date as object this doesn't work? Isn't the reason to use date filed is to take advantage of quering with DateTime objects? I guess I'm missing something trivial and important, but I just can't see what, or I'm not understanding the situation quite well. My understanding is like this: the field is of type date, so I should insert DateTime objects in it and when quering I should also you DateTime objects. Can you please help me to fix this?
P.S.: I tried changing the field to datetime:
/**
* #ORM\Column(type="datetime")
*/
protected $date;
but there was no change.
And at all is it OK and good to query with string? Will I get the advantage of using objects when querying that way?

I think this is because a DateTime object is too much specific and have also hours, minutes and seconds, so it can't be equal to a registered date in database !
If you want to use DateTime objects, you need to get the date of the beginning of the day and the end date to get all results of the day ! You must compare an interval of dates to get all dates between it.
First, get the start and the end dates of the current day (to simplify, we will base the end date on the beginning of the next day, and we will exclude it in the request) :
$fromDate = new \DateTime('now'); // Have for example 2013-06-10 09:53:21
$fromDate->setTime(0, 0, 0); // Modify to 2013-06-10 00:00:00, beginning of the day
$toDate = clone $fromDate;
$toDate->modify('+1 day'); // Have 2013-06-11 00:00:00
And modify your method :
public function findExpensesForDate($user, $fromDate, $toDate)
{
$q = $this
->createQueryBuilder('e')
->where('e.date >= :fromDate')
->andWhere('e.date < :toDate')
->andWhere('e.user = :user')
->setParameter('fromDate', $fromDate)
->setParameter('toDate', $toDate)
->setParameter('user', $user)
->getQuery();
return $q->getResult();
}
That's all, it should work, here the script :
$expenses_for_today = $this->repository->findExpensesForDate($this->user, $fromDate, $toDate);
So you will get all the dates between the 2013-06-10 00:00:00 and the 2013-06-11 00:00:00 (excluded), so the results of the day !

As others have mentioned, thats due to the time in DateTime.
Yet why am I answering?
Because I want to make you aware of the $qb->expr()->between()function.
The following snippet is from my ReservationRepository where I need to find the reservations for a given date ($today). My reservations have both a dateFrom and a dateTo attribute.
if(null !== $today) {
$today0 = new \DateTime($today->format("Y-m-d"));
$today23 = new \DateTime($today->format("Y-m-d"));
$today0->setTime(0,0,0);
$today23->setTime(23,59,59);
$qb->where($qb->expr()->orX(
$qb->expr()->orX(
$qb->expr()->between('r.dateFrom', ':today0', ':today23'),
$qb->expr()->between('r.dateTo', ':today0', ':today23')
),
$qb->expr()->andX(
$qb->expr()->lte('r.dateFrom', ':today23'),
$qb->expr()->gte('r.dateTo', ':today0')
)
));
$qb->setParameter('today0', $today0);
$qb->setParameter('today23', $today23);
}
The function between() saves me two lines of code in this example, and I find it to be more readable.

Related

how to increment 1 value in email address for uniqueness in selenium webdriver

I am writing test script for signup page and i need to put email address on each time. Can someone help me how to increment by value 1 in the email address as i execute the script for example, test#test.com and next time value should be test1#test.com. I an try with time stamp but not successfully work.
public class GetCurrentTimeStamp
{
public static void main( String[] args )
{
java.util.Date date= new java.util.Date();
System.out.println(new Timestamp(date.getTime()));
}
}
If you are trying to provide always unique email id, then you can use date with seconds as it keep changing also you can use
System.currentTimeMillis()
which gives number always unique. so you can append/concatenate it to email, i hope you know it.
You can use below code to get date
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
System.out.println(dateFormat.format(date)); //2016/04/19 16:05:48
depends of simple date format provide 'yyyy/MM/dd HH:mm:ss' output will be displayed.
Thank You,
Murali
Use java.util.Date class instead of Timestamp and format it like so.
String timeStamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
String email= "test"+ timestamp + "#test.com";
Use below code:-
int num = 1; // Put this stament outside the for loop or put it as global variable.
Now use below code :-
num++;
String email= "test"+ num + "#test.com";
Hope it will help you :)

breezejs: date is not set to the right time

I've noticed that if a date property comes back from the server with the value "2013-07-11T17:11:04.700", then breeze changes the value to Thu Jul 11 19:11:04 UTC+0200 2013.
Notice the time is now 2 hours ahead !
I had already come across this issue when saving entities, so I had to explicitly convert my date properties using momentjs :
date.hours(date.hours() - moment().zone() / 60);
But now it seems the problem occurs also when doing read operations.
What's the best way to make sure breeze does not alter values of my date properties ?
Breeze does not manipulate the datetimes going to and from the server in any way EXCEPT to add a UTZ timezone specifier to any dates returned from the server that do not already have one. This is only done because different browsers interpret dates without a timezone specifier differently and we want consistency between browsers.
The source of your issues is likely to be that when you save your data with dates to the database, that the dateTime datatype you are using does NOT contain a timezone offset. This means that when the data is retrieved you are likely "losing" the offset and the Breeze default mentioned above kicks in. This can be corrected by using a database date time datatype with an timezone offset ( datetime2 or datetimeoffset in SQLServer).
Note that your browser DOES format dates according to it's current timezone.
Another approach is that you can replace Breeze's DataType.parseDateFromServer to NOT infer any time zone info if it is not provided:
breeze.DataType.parseDateFromServer = function (source) {
return new Date(Date.parse(source));
};
However, this can run into the problem that different browsers interpret DateTime strings without a time zone offset differently... So you may still get strange results depending on the browser. If that happens you will need to add some browser detection code to the snippet above.
Another alternative is to do the following using the moment.js library.
breeze.DataType.parseDateFromServer = function (source) {
var date = moment(source);
return date.toDate();
};
Not sure how helpful this is, but hopefully Breeze's behavior is clearer.
By default, Breeze does not provide any way to do this, but you can keep the below code in your model JS file to overcome this issue:
breeze.DataType.parseDateFromServer = function (source) {
if (typeof source === 'string') {
//Check for local offset time or UTC time from server
if (source.slice(-1) !== "Z") {
var oldSource = source;
try {
source = source.substring(0, source.lastIndexOf("-") - 1)
source = new Date(source);
var tzDifference = source.getTimezoneOffset();
//convert the offset to milliseconds, add to targetTime, and make a new Date
var offsetTime = new Date(source.getTime() + tzDifference * 60 * 1000);
return offsetTime;
}
catch (err) {
source = new Date(source);
return source;
}
}
else {
source = new Date(source);
var tzDifference = source.getTimezoneOffset();
//convert the offset to milliseconds, add to targetTime, and make a new Date
var offsetTime = new Date(source.getTime() + tzDifference * 60 * 1000);
return offsetTime;
}
}
}

Grails matching dates

I have a string which is:
"may 2013"
This refers to the second of May. I am trying to get all instances of PostOrder where the date is the second of May.
What I have tried so far:
def t = new Date(new Integer(sp[1]), new Integer(month), 01)
def results = PostOrder.createCriteria().list() {
ilike('dateCreated', t )
}
Please note I have split the string so sp[1] is 2013 and I have parsed the May so the month variable is not 05.
The above attempt does not work.
The only way I know will work is grabbing all objects and doing a for each on them. parsing the dateCreated to a string then doing a .contains(). But this will get very slow and messy.
First point. According to the documentation, ilike() is a case-insensitive 'like' expression - see SQL LIKE Operator. So, it cannot accept a date. What you need is just eq().
def t = new Date(new Integer(sp[1]), new Integer(month), 1)
def results = PostOrder.createCriteria().list() {
eq('dateCreated', t)
}
Another point. The constructor Date() accepts the year minus 1900 as the first argument. So, you probably need to subtract 1900 from new Integer(sp[1]).
Also, that constructor is deprecated; I would suggest to use GregorianCalendar(new Integer(sp[1]), new Integer(month), 1).time.

Validating two dates in acrobat javascripts

well the code I posted below all works perfectly except for a small detail. When I input today date in the field dateEntered, the later rejects it, it validates if the date entered is before todays date, validate if the date falls on a weekends, but it also show an error message when it is todays date. Actually the user should be able to enter Today or after date.
Anyone can tell me where am wrong, already tried every possible ways but still not working even the ( ==) or (===) or (<=) ..nothing
if (event.value!="")
{
var e = util.scand("ddd, dd.mmm.yy", event.value);
var a = (e.getTime()) < (new Date().getTime());
if (a) {
app.alert("The Date cannot be before Today's Date", 1);
event.rc = null;
}
if (e.getDay()==6 || e.getDay()==0) {
app.alert("Cannot take permission on a Weekend!", 2);
event.rc=null;
}
}
I found the solution to my problem, I had to set the hour to 0. Thank to the one who updated this on stackoverflow and sorry forget to retain your name.
if (event.value!="")
{
var e = util.scand("ddd, dd.mmm.yy", event.value);
var b=new Date();
b.setHours(0,0,0,0);
if (e<b) {
app.alert("ERROR: Date cannot be before"+" "+ new Date(b), 5);
event.rc = null;
}
if (e.getDay()==6 || e.getDay()==0) {
app.alert("ALERT: The date you entered ("+event.value+") falls on a WEEKEND!", 3);
event.rc=null;
}
}
This codes also contains a condition of removing one weekend from the dates since the number of leaves allowed to take ranges from 1 to 7 thus only one weekend is remove.

How to convert nthWeek and nthMonth to date?

I am trying to get weekly and monthly visitor totals with Google Analytics API for the last X years. I set:
metrics=ga:visitors
dimensions=ga:nthWeek (or nthMonth)
It returns the data I want:
0 week : 100 visitors
1 week : 200 visitors
2 week : 300 visitors
Only instead of week 0 I want it to be displayed as 01/01/2012. How do I convert Nth week (or month) to date?
I tried:
Passing ga:date as metrics (which would be a logical thing to do, similar to how it's done in SQL), but it doesn't recognize it as a valid metrics.
Passing ga:date as the second dimension prevents weekly grouping.
You don't mention what language you're using, so I don't know what sort of date-wrangling interfaces you have available to you, but ga:week,ga:year should provide you with the week of the year that you can plug in and allow you to build the date appropropriately. In PHP it might be something like the following:
<?php
// assuming use of the official PHP API for Google services, and
// that you've appropriately initialized the connection, and that
// you've chosen to "$client->setUserObjects(true)", and that you've
// initialized the necessary variables...
$results = $service->data_ga->get($analytics_id, $start_date, $end_date, 'ga:visitors',
array('dimensions' => 'ga:week,ga:nthWeek,ga:year'));
$columns = array();
foreach ($results->columnHeaders as $headidx => $col) {
$columns[$col->name] = $headidx;
}
$traffic = array();
foreach ($results->rows as $idx => $week) {
$date = new DateTime;
$date->setISODate($week[$columns['ga:year']], $week[$columns['ga:week']]);
$traffic[$week[$columns['ga:nthWeek']]] = array('date' => $date, 'visitors' => $week[$columns['ga:visitors']], 'visits' => $week[$columns['ga:visits']], 'pageviews' => $week[$columns['ga:pageviews']]);
}
ksort($traffic);
// $traffic now holds a sorted array of your week by week traffic, with the full
// date in the DateTime object that you can access and format however you please
?>