Compare Groovy dates ignoring days - datetime

How can I compare dates in Groovy ignoring days? Something like this: *MM-yyyy_1 > MM-yyyy_2*

You could do this:
int compareIgnoringDays( Date a, Date b ) {
new Date( a.time ).with { newa ->
new Date( b.time ).with { newb ->
newa.set( date:1 )
newb.set( date:1 )
newa.compareTo( newb )
}
}
}
Which you can test like:
Date a = Date.parse( 'yyyy/MM/dd', '2012/05/23' )
Date b = Date.parse( 'yyyy/MM/dd', '2012/05/24' )
Date c = Date.parse( 'yyyy/MM/dd', '2012/06/01' )
assert compareIgnoringDays( a, b ) == 0
assert compareIgnoringDays( b, a ) == 0
assert compareIgnoringDays( a, c ) == -1
assert compareIgnoringDays( c, a ) == 1
A different way of writing the same functionality is:
int compareIgnoringDays( Date a, Date b ) {
[ a, b ].collect { new Date( it.time ) } // Clone original dates
.collect { it.set( date:1 ) ; it } // Set clones to 1st of the month
.with { newa, newb ->
newa.compareTo( newb ) // Compare them (this gets returned)
}
}

You can compare two dates like this:
def myFormat = 'MM/dd/yyyy'
if(Date.parse(myFormat, '02/03/2012') >= Date.parse(myFormat, '03/02/2012))
{...}

Related

hash table/pscustomobject instead of switch block

Is there a way to use hash table or pscustomobject instead of switch block below? hash table seems like a great way to simplify the function.
function Get-Farm
{
[cmdletbinding()]
param (
[parameter (Mandatory = $true)]
[string]$farm)
Process{
switch($farm){
A {
$script:startHostID = 0
$script:endHostID = 0
}
B {
$script:startHostID = 1
$script:endHostID = 12
}
C {
$script:startHostID = 13
$script:endHostID = 24
}
BC {
$script:startHostID = 1
$script:endHostID = 24
}
ALL {
$script:startHostID = 1
$script:endHostID =48
}
}
}
Indeed, hashtable lookup is a better alternative.
Create the lookup table in Begin block and use it in Process.
Also, use ValueFromPipeline in parameter description, otherwise don't use Process.
function Get-Farm
{
[cmdletbinding()]
param (
[parameter(Mandatory, ValueFromPipeline)]
[string]$farm
)
Begin {
$lookup = #{
A = 0,0
B = 1,12
C = 13,24
BC = 1,24
ALL = 1,48
}
}
Process {
if ($values = $lookup[$farm]) {
$script:startHostID = $values[0]
$script:endHostID = $values[1]
}
}
}
I've used the assignment inside if() to condense the code but of course you can write it separately:
$values = $lookup[$farm]
if ($values) {

Symfony 2 Bizarre behavior in the controller

Symfony 2.3
I have two fields on the form with dates: the date_from and date_to.
The controller after submit performs its own validation. After automatic validatin is OK make my own validation of dates. Before adding the code below the form and submit displays after validation:
date_from 2015-10-01 and date_to 2015-10-02
and after adding the code form displays before submit:
date_from 2015-10-01 and date_to 2015-10-02
after submit:
date_from 2015-10-02 and date_to 2015-10-01
Dates are switched. So it writes to the database.
$date_from = $entity->getDatefrom();
$date_to = $entity->getDateto();
$workdays = 0;
for ( $i = $date_from; $i <= $date_to; $i->setTimestamp(strtotime($i->format('Y-m-d') . " +1 day") ) )
{
if ( !in_array($i, $freedays))
{
if ( date('N', strtotime($i->format('Y-m-d') ) ) < 6 )
{
$workdays++ ;
}
}
}
When i remove this code dates are not switched. But ofcourse i don't have count of working days.
You need to dereference the DateTime Object $date_from using clone before assigning it to $i.
http://php.net/manual/en/language.oop5.references.php
$date_from = $entity->getDatefrom();
$date_to = $entity->getDateto();
$workdays = 0;
for ( $i = clone $date_from; $i <= $date_to; $i->setTimestamp(strtotime($i->format('Y-m-d') . " +1 day") ) )
{
if ( !in_array($i, $freedays))
{
if ( date('N', strtotime($i->format('Y-m-d') ) ) < 6 )
{
$workdays++ ;
}
}
}
PHP doesn't copy objects when assigning them to a new variable it just creates a reference.
$i = $date_from
In this for loop it updates the $i for each iteration
$i->setTimestamp(strtotime($i->format('Y-m-d') . " +1 day") )
Because it's only a reference its this same as
$date_from->setTimestamp(strtotime($i->format('Y-m-d') . " +1 day") )
// OR even
$entity->getDatefrom()->setTimestamp(strtotime($i->format('Y-m-d') . " +1 day") )
Using clone make a copy of the original so $i->setTimestamp(...) won't actually apply to $date_from

Conditional display of start and end dates (PHP/Wordpress)

(As you can tell from this post I am not a programmer, so please help me to see if this is even possible... )
I want to improve the Start / End date display for events in Events Manager (plugin for WordPress)
At the moment the the end times will only show up if different then the start date (good!) but will be in the format:
1 January 2014 - 31 January 2014.
I would like it to display as: 1 - 31 January 2014.
That isn't too hard, but it becomes a little more complicated when events wrap or extend past a month, or a year.
Here are the different cases I am trying to achieve:
Start date only:
1 January 2014
Start and end date in same month
1 – 12 January 2014
Start and end date in different month but same year.
28 January – 3 February 2014
Start and end date in different months and different years.
31 December 2014 – 3 January 2015
Can anyone tell me
a) if this is at all possible to do with a function in the WordPress functions file?
and
b) point me in the right direction on how to do the conditioning?
I don't even know what to google for, so even that would be a help. (I am not expecting a fully working code example, although you are more then welcome to include that if you want!)
Update: Here is an example of a function that does some of this, but only in the style of the last case in my list above.
add_filter('em_event_output_placeholder','my_em_placeholder_mod_eventdates',1,3);
function my_em_placeholder_mod_eventdates($replace, $EM_Event, $result){
if ( $result == '#_EVENTDATES' ) {
if( $EM_Event->event_start_date != $EM_Event->event_end_date){
$replace = date_i18n('d M Y', $EM_Event->start).' - '. date_i18n('d M Y', $EM_Event->end);
}else{
$replace = date_i18n('d M Y', $EM_Event->start);
}
}
return $replace;
}
Update 2, with working code:
This code works for me at least.
add_filter('em_event_output_placeholder','my_em_placeholder_mod_eventdates',1,3);
function my_em_placeholder_mod_eventdates($replace, $EM_Event, $result){
if ( $result == '#_EVENTDATES' ) :
$sd = $EM_Event->start;
$ed = $EM_Event->end;
if (!empty ($ed) && $sd != $ed ) {
//Event has an end date and end date is different than start date
if (date('Y', $sd) == date('Y', $ed)) {
// Start and end are in same year
if (date('n', $sd) == date('n', $ed)) {
//Start and end are in the same month
$replace = date_i18n('j', $sd).'-'.date_i18n('j F Y', $ed);
if (date('j', $sd) == date('j', $ed)) {
//Start and end are on the same day
$replace = date_i18n('j F Y', $sd);
}
} else {
//Start and end are in different months
$replace = date_i18n('j F', $sd).' - '.date_i18n('j F Y', $ed);
}
} else {
//Start and end are in different years
$replace = date_i18n('j F Y', $sd).' - '. date_i18n('j F Y', $ed);
}
} else {
// No end date, or start and end date are the same
$replace = date_i18n('j F Y', $sd);
}
endif;
return $replace;
}
Try this:
add_filter('em_event_output_placeholder','my_em_placeholder_mod_eventdates',1,3);
function my_em_placeholder_mod_eventdates($replace, $EM_Event, $result){
if ( $result == '#_EVENTDATES' ) :
$sd = $EM_Event->event_start_date;
$ed = $EM_Event->event_end_date;
if (!empty ($ed) && $sd != $ed ) {
//Event has an end date and end date is different than start date
if (date('Y', $sd) == date('Y'. $ed) {
// Start and end are in same year
if (date('n', $sd) == date('n', $ed) {
//Start and end are in the same month
$replace = date_i18n('j', $sd).'-'.date_i18n('j F Y', $ed);
} else {
//Start and end are in different months
$replace = date_i18n('j F', $sd).' - '.date_i18n('j F Y', $ed);
}
} else {
//Start and end are in different years
$replace = date_i18n('j F Y', $sd).' - '. date_i18n('j F Y', $ed);
}
} else {
// No end date, or start and end date are the same
$replace = date_i18n('j F Y', $sd);
}
endif;
return $replace;
}

How can I create new map with new values but same keys from an existing map?

I have an existing map in Groovy.
I want to create a new map that has the same keys but different values in it.
Eg.:
def scores = ["vanilla":10, "chocolate":9, "papaya": 0]
//transformed into
def preference = ["vanilla":"love", "chocolate":"love", "papaya": "hate"]
Any way of doing it through some sort of closure like:
def preference = scores.collect {//something}
You can use collectEntries
scores.collectEntries { k, v ->
[ k, 'new value' ]
}
An alternative to using a map for the ranges would be to use a switch
def grade = { score ->
switch( score ) {
case 10..9: return 'love'
case 8..6: return 'like'
case 5..2: return 'meh'
case 1..0: return 'hate'
default : return 'ERR'
}
}
scores.collectEntries { k, v -> [ k, grade( v ) ] }
Nice, functional style solution(including your ranges, and easy to modify):
def scores = [vanilla:10, chocolate:9, papaya: 0]
// Store somewhere
def map = [(10..9):"love", (8..6):"like", (5..2):"meh", (1..0):"hate"]
def preference = scores.collectEntries { key, score -> [key, map.find { score in it.key }.value] }
// Output: [vanilla:love, chocolate:love, papaya:hate]
def scores = ["vanilla":10, "chocolate":9, "papaya": 0]
def preference = scores.collectEntries {key, value -> ["$key":(value > 5 ? "like" : "hate")]}
Then the result would be
[vanilla:like, chocolate:like, papaya:hate]
EDIT: If you want a map, then you should use collectEntries like tim_yates said.

fullCalendar Comparing Times

on the select event i have the starting date and the ending date of the event as parameter.
also i have a list of times
and i want to see if any of the items of my list is between of the event start and endtime
the 3 objects are in Date Format
how can i compare the 3 Times of the Dates to see if if its true????
select: function (start, end, allDay) {
var defaultTemplate = undefined;
$.each(jsonTimeTemplates, function(){
templateStartTime = $.fullCalendar.parseDate(this.Start);
templateEndTime = $.fullCalendar.parseDate(this.End);
if(( templateStartTime.getTime() >= start.getTime()) && ( templateStartTime.getTime() <= end.getTime())){
defaultTemplate = this;
}
});
},
in this case jsonTimeTemplates is my list of objects but when i debug with firebug the if sentence never applies.
here i have an screenshot of my debugging where i have
8:00>=8:00 && 8:00 <= 8:15
i hope the dates arent making the problem here.
function compareDates(dateFrom, dateTo){
if ( Date.parse( dateTo ) < Date.parse( dateFrom ) )
return true;
return false;
}
This function returns true if dateTo is smaller than dateFrom. You can use this function to reach your goal.
Function call:
var startDateStr = $.fullCalendar.formatDate(start, 'MM/dd/yyyy hh:mm tt');
var endDateStr = $.fullCalendar.formatDate(end, 'MM/dd/yyyy hh:mm tt');
compareDates(startDateStr, endDateStr);
in the mean time i used the functions gethours and getminutes to do the comparisons. but i hope theres a better way to do this
if( ( templateStartTime.getHours() >= start.getHours() ) && ( templateStartTime.getHours() <= end.getHours() ) &&
(templateStartTime.getMinutes() >= start.getMinutes() ) && ( templateStartTime.getMinutes() <= end.getMinutes() ))
{
defaultTemplate = this;
}

Resources