I have a date format as '12-FEB-2014' I need to convert it to 'yyyy-mm-dd' format. I tried this:
xdmp:parse-dateTime("[D01]-[MN,*-3]-[Y0001]","12-FEB-2014")
But it throws an exception:
XDMP-PATTERNVALUEMISMATCH: Given value doesn't match with the specified pattern
for parsing dateTime string
It looks like with the month that you have you will have to make your own transform function. This code down below should give you a start. It will work off the example you gave us.
declare function local:month-name-to-int
( $stringIN as xs:string? ) as xs:string? {
switch (fn:lower-case($stringIN))
case "jan" return "01"
case "feb" return "02"
case "mar" return "03"
case "apr" return "04"
case "may" return "05"
case "jun" return "06"
case "jul" return "07"
case "aug" return "08"
case "sep" return "09"
case "oct" return "10"
case "nov" return "11"
case "dec" return "12"
default return fn:error(xs:QName("ERROR"), "unknown month")
} ;
let $string := "12-FEb-2014"
let $stringTokened := fn:tokenize($string, "-")
return xs:date($stringTokened[3] || "-"||local:month-name-to-int($stringTokened[2]) || "-" || $stringTokened[1])
Related
I have a value which can be one of 3 strings, or NULL. When the value is NULL the following code does not work
value <- NULL
if( value == "test" ){
print("1")
} else {
print("2")
}
It seems I have to write the code as below to make it work:
if ( !is.null(value) && value== "test" ) {
print("1")
} else {
print("2")
}
Writing it like that however seems unnecessarily complicated and messy.
Is there a cleaner way to do this?
You could surround the condition with isTRUE()
value <- NULL
if ( isTRUE(value == "test") ) {
print("1")
} else {
print("2")
}
# [1] "2"
or replace == with identical():
identical(value, "test")
# [1] FALSE
You can use function setequal in base R:
value <- NULL
setequal(value, "test")
[1] FALSE
How about using %in% operator:
if( "test" %in% value){
print("1")
} else {
print("2")
}
[1] "2"
I've got a sequence that needs to sort a list based off earliest year vs. latest year. Due to some unique values in the year element, it is making the sort a little more complicated. Is there any way to achieve the following?
let $dates := ('1982', '2019', '2095', 'pre-1982', 'post-2095')
return
for $date in $dates
order by $date
return $date
the dates element text is usually the year in the data, but outlier cases have a pre- or post- attached. Any way to achieve this minimally?
I am not sure if this is minimal, but it works:
let $dates := ('1982', '2019', '2095', 'pre-1982', 'post-2095')
return
for $date in $dates
let $year :=
if (fn:contains($date, "-"))
then fn:substring-after($date, "-")
else $date
let $prepost :=
if (fn:starts-with($date, "pre"))
then -1
else if (fn:starts-with($date, "post"))
then 1
else 0
order by $year, $prepost
return $date
Just FYI: Definitely not minimal, but I wanted to know what fn:sort does when a sequence is returned. Turns out it does the right thing.
xquery version "3.1";
declare variable $local:ascending := 1;
declare variable $local:descending := -1;
declare function local:sort-prefixed-years ($y, $order) {
if (fn:contains($y, "-"))
then (
let $p := fn:tokenize($y, "-")
let $m :=
switch($p[1])
case "pre" return -1 * $order
case "post" return 1 * $order
default return 0
return (xs:integer($p[2]) * $order, $m)
)
else (xs:integer($y) * $order, 0)
};
declare function local:sort-prefixed-years-ascending ($prefixed-year) {
local:sort-prefixed-years($prefixed-year, $local:ascending)
};
declare function local:sort-prefixed-years-descending ($prefixed-year) {
local:sort-prefixed-years($prefixed-year, $local:descending)
};
let $dates := ('1982', '2019', '2095', 'pre-1982', 'post-2095')
return sort($dates, (), local:sort-prefixed-years-descending#1)
I am trying this code on MarkLogic console and getting this error
Unexpected token syntax error, unexpected If_
Here is the code
let $name1 := "Bob"
let $name2 := "John"
if(fn:contains($name1, "Bo")) then
return "Bob is good"
else
return "John is good"
Your syntax is wrong. Try this-
let $name1 := "Bob"
let $name2 := "John"
return
if (fn:contains($name1, "Bo")) then
"Bob is good"
else
"John is good"
This is my code:
If FinalMonth = "" OR FinalYear = "" Then
FinalMonth = Month(Now())
FinalYear = Year(Now())
End If
Select Case(FinalMonth)
Case "01","03","05","07","08","10","12"
FinalDay = "31"
Case "04","06","09","11"
FinalDay = "30"
Case "02"
If ( (FinalYear Mod 4) <> 0 ) Then
FinalDay = "28"
Else
FinalDay = "29"
End If
End Select
I want to set my month with 0 before the number 1 (January) per example, and finally Month 01. How can I do it please?
You can;
If FinalMonth = "" OR FinalYear = "" Then
FinalMonth = Month(Now())
FinalYear = Year(Now())
End If
'get last day of month - add 1 month then deduct 1 day
FinalDay = Day(DateSerial(FinalYear, FinalMonth + 1, 1) - 1)
'pad month
if (FinalMonth < 10) then FinalMonth = "0" & FinalMonth
what about this ?
<%=Right("0" & Day(now()), 2)%>-<%=Right("0" & Month(now()), 2)%>-<%=Year(now())%>
Output : 10-02-2018
I have dates stored in array for completion status of projects like below
The first two letters are months and other four letters are years
052012(mmyyyy)
$arrDates = array('052012', '042013', '082013', '122013', '022014');
I want this array To get converted to wordings as below
$arrDates = array('Completed', 'Next Six Months', 'Next Year', 'Next Year', 'After 2 Years');
I used a for loop like below for checking completed as below
for($i=0;$i<count($arrDates);$i++)
{
if((date('m') > substr($arrDates[$i], 0,2)) && (date('y') == substr($arrDates[$i], 2,6)))
$strStatus = ' Completed';
}
and I messed up in finding for next year and other two.
Could some one help me in fixing this?
I think you can use DateTime and dateInterval for this :
$currentDate = DateTime::createFromFormat('mY',$arrDates[0]);
$interval = $currentDate->diff(new DateTime('now'),true);
if($interval->invert){
echo 'Completed';
else if($interval->y >= 2 ){
echo 'After 2 Years';
}
else if($interval->y == 1){
echo 'Next Year';
}
else if($interval->m > 6){
echo 'what you want here';
}
else {
echo 'Next six months';
}
I think artragis was on the right track with his answer (+1 for that), but the whole thing should be encapsulated in a function for re-use.
/**
* #param string $expectedDate
* #return string Text summary of time to completion
*/
function completionTimeInWords($expectedDate)
{
$now = new DateTime();
$date = new DateTime();
$date->setTimestamp(strtotime('+1 year'));
$oneYear = $date->diff($now)->days;
$sixMonths = round($oneYear/2);
$date->setTimestamp(strtotime('+2 years'));
$twoYears = $date->diff($now)->days;
$date = DateTime::createFromFormat('mY', $expectedDate);
$interval = $now->diff($date);
$completed = (bool)$interval->invert;
$days = $interval->days;
if($completed){
return 'Completed';
} elseif($days <= $sixMonths){
return 'Next Six Months';
} elseif($days > $sixMonths && $days <= $oneYear){
return 'Within a year';
} elseif($days > $oneYear && $days <= $twoYears){
return 'Next Year';
} elseif($days > $twoYears){
return 'After Two Years';
}
}
I tested this with the following code:-
$date = new DateTime();
$date->setTimestamp(strtotime('two weeks ago'));
$arrDates[] = $date->format('mY');
$date->setTimestamp(strtotime('+ 5 months 27 days'));
$arrDates[] = $date->format('mY');
$date->setTimestamp(strtotime('+ 6 months 4 days'));
$arrDates[] = $date->format('mY');
$date->setTimestamp(strtotime('+ 12 months 4 days'));
$arrDates[] = $date->format('mY');
$date->setTimestamp(strtotime('+ 24 months 4 days'));
$arrDates[] = $date->format('mY');
foreach($arrDates as $date){
var_dump(completionTimeInWords($date));
}
and got the following output:-
string(9) "Completed"
string(15) "Next Six Months"
string(13) "Within a year"
string(9) "Next Year"
string(15) "After Two Years"
You may need to do some more testing with edge cases as these can be problematic. For example, most of us would agree that 6 months is 183 days, but PHP may disagree on occasion depending on how many days are in each month between now and 6 months hence (if that makes sense). That is why I have divided a year by 2 to get 6 months, rather than using strtotime().