I am trying to get the difference between two dates in months for an xPath.
I have no problems getting it in days (1127)
days-from-duration(xs:date('2012-06-17')-xs:date('2009-05-17'))
When I try doing it in months I get 0
months-from-duration(xs:date('2012-06-17')-xs:date('2009-05-17'))
I did notice that this comes back as days only ("P1126D") so that maybe the problem just not sure how to fix it.
xs:date('2012-06-17')-xs:date('2009-05-17')
Thanks for any help!
So the best thing I can seem to do is manually calculate it.
(year-from-date(xs:date('2012-06-17')) - year-from-date(xs:date('2012-05-18')))*12 + month-from-date(xs:date('2012-06-17')) -month-from-date(xs:date('2012-05-18')) + (if (day-from-date(xs:date('2012-06-17')) < day-from-date(xs:date('2012-05-18')) ) then -1 else 0)
This function was not included in the spec because we couldn't agree semantics for it. We heard arguments that the difference between 31 March 2015 and 30 Sept 2015 was six months, and arguments that it was five months. (Advice: negative differences seem to be even more problematic than positive differences.) You can easily find that a date plus 6 months minus 6 months is not the date where you started. You'll have to define what you think the answer should be, and implement it using lower-level facilities such as month-from-date and year-from-date.
The problem is that days-from-duration returns the days field -- not the number of days the duration includes. Likewise for months and years.
Now, you can divide by days, but not by months (since months have uneven boundaries):
(: arg1 here is a dayTimeDuration, which can't be easily converted to a yearMonthDuration :)
let $arg1 := xs:date('2012-06-17')-xs:date('2009-05-17')
return xs:dayTimeDuration($arg1) div xs:dayTimeDuration("P30D")
Related
I'm trying to use a relatively basic IF function but having no luck - i'm sure i just have brackets or parenthesis wrong or something. Reckon it will be childsplay for you guys....
The formula is intended to show how many days a date has passed by. Date is shown in T column.
Basically it was working fine as the following, both for pending and past dates:
=IF(T7<=TODAY(), (TODAY()-T7),-(T7-TODAY()))
But I got greedy and wanted it to return more of a statement when the date has passed, as to how much it has passed by. So I've tried to make this happen with:
=IF(T7<=TODAY(),"EffOut(TODAY()-T7) days ago",-(T7-TODAY()))
Hoping it would enter "EffOut 8 days ago" (when TODAY()-T7 is 8 days) for example.
But it doesnt - it shows the entire argument i.e "EffOut(TODAY()-T7) days ago" in the return cell.
Is it possible to have a kind of embedded formula in the 'value_if' fields, mixed with text in this sense?
Happy to share the document if that would help, but will need to clear the data first so just let me know.
Thanks in advance, any help is much appreciated! Having read other posts I think it will just be a simple fix but its well beyond me! (I only got this far by perusing forums...)
Maybe something like this...
=IF(T7<=TODAY(),"EffOut "&DAYS(TODAY(),T7)&" days ago",-(T7-TODAY()))
=IF(T7<=TODAY(),"EffOut "&(TODAY()-T7)&" days ago",-(T7-TODAY()))
You just need to be careful to put "" around any strings. This is how Excel knows that's not a part of the formula. Remember to out the spaces is to the string like I did above so it looks like a sentence. The & sign combines the results of the calculated parts and the strings.
How would I get the age of a file in days in Ruby?
NOTE that I need a way to accurately get the age of a given file; this means that leap years need to be taken into account.
I need this for a program that removes files after they reach a certain age in days, such as files that are 20 days or older.
And by age, I mean the last access time of a given file, so if a file hasn't been accessed in the past 20 days or more, it gets deleted.
In Perl, I know that you can use date::calc to calculate a date in terms of days since 1 AD, and I used to have a Common-Lisp program that used the Common-Lisp implementation of date::calc, but I don't have that anymore, so I've been looking for an alternative and Ruby seems to have the required capability.
path = '/path/to/file'
(Time.now - File.stat(path).mtime).to_i / 86400.0
#=> 1.001232
Here is the implementation of my above comment, it returns a floating point number expressing the number of days passed.
I know it is an old question, but I needed the same and came up with this solution that might be helpful for others.
As the difference is in days, there is not need to directly deal with seconds.
require 'date'
age_in_days = (Date.today - File.mtime(path).to_date).to_i
if age_in_days > 20
# delete logs
end
If using Rails, you can take advantage of ActiveSupport:
if File.mtime(path) < 20.days.ago
# delete logs
end
If you aren't using Rails, Eduardo's solution above would be my pick.
Drools seems to support only days, hours, minutes, seconds and milliseconds for the units of time used with Temporal Operators. I am working on a rule that looks for people within a particular age group. For example: between 6 months and 5 years, younger than 18 years, older than 12 years etc..
My person Class has a dateOfBirth instance variable, but no person.age method to do a direct comparison like:
$p : Person(age <= 18)
I don't have too much liberty to modify the Person Class and I am trying to avoid writing utils methods and using 'eval' for comparing, as 'evals' are not optimized. I am a drools newbie and have written the following rule.
rule "Under18Years"
when
now : RuleTime()
$p : Person(dateOfBirth after[-6570d, 0s] $now )
then
System.out.println("Under18Years fired");
end
I know this isn't very accurate as I just used 6570 (365*18) days; ignoring the leap years. I might be better off using seconds in a standard SI year (31,556,926) times 18 to account for 18 years, but is there a better way? This doesn't work for conditions involving months either. Does anyone have any other ideas/solution to this problem?
You can create a package or a function that does the above
public int getAge() {
Years years = Years.yearsBetween(dateOfBirth, currentDate);
return years.getYears();
For aslong as i have been using drools there has allways been years available to call upon. i see this was posted a while ago and maybe you have found out since.
Is there a way to represent dates like 12/25 without year information? I'm thinking of just using an array of [month, year] unless there is a better way.
You could use the Date class and hard set the year to a leap year (so that you could represent 2/29 if you wanted). This would be convenient if you needed to perform 'distance' calculations between two dates (assuming that you didn't need to wrap across year boundaries and that you didn't care about the off-by-one day answers you'd get when crossing 2/29 incorrectly for some years).
It might also be convenient because you could use #strftime to display the date as (for example) "Mar-3" if you wanted.
Depending on the usage, though, I think I would probably represent them explicitly, either in a paired array or something like YearlessDate = Struct.new(:month,:day). That way you're not tempted to make mistakes like those mentioned above.
However, I've never had a date that wasn't actually associated with a year. Assuming this is the case for you, then #SeanHill's answer is best: keep the year info but don't display it to the user when it's not appropriate.
You would use the strftime function from the Time class.
time = Time.now
time.strftime("%m/%d")
While #Phrogz answer makes perfect sense, it has a downside:
YearlessDate = Struct.new(:month,:day)
yearless_date = YearlessDate.new(5, 8)
This interface is prone to MM, DD versus DD, MM confusion.
You might want to use Date instead and consider the year 0 as "yearless date" (provided you're not a historian dealing with real dates around bc/ad of course).
The year 0 is a leap year and therefore accommodates every possible day/month duple:
Date.parse("0000-02-29").leap? #=> true
If you want to make this convention air tight, just define your own class around it, here's a minimalistic example:
class YearlessDate < Date
private :year
end
The most "correct" way to represent a date without a year is as a Fixnum between 001 and 365. You can do comparisons on them without having to turn it into a date, and can easily create a date for a given year as needed using Date.ordinal
Is there a way to get a 2 character day-name of the week such as MO/TU/WE/TH/FR/SA/SU?
Currently I only know of using FormatDateTime():
"ddd" returns "Fri"
"dddd" returns "Friday"
The main reason is that I want to obtain localized version of the 1 or 2 character day names:
Say FRIDAY in "ddd" would return:
French Windows = "Vendredi", the 2 char would be "VE", note it's the 1st and 2nd char.
Chinese Windows = "星期五", the char would be "五", note it's the 3rd char.
Japanese Windows = "金曜日", the char would be "金", note it's the 1st char.
Edit1:
Currently using Delphi, but i think applies to other languages too.
Edit2:
Simply put, I'm looking to obtain the shorter version of "ShortDayName" through the use of some functions or constants, so that I don't have to build a table of constants containing the 7 day "Shorter" day names for every possible windows language.
I wonder if such functions really exist.
Maybe the calendar 1 or 2 char day names in Outlook are hard-coded themselves, right?
You can get the local names for the days of the week with ShortDayNames and LongDayNames, and you can use DayOfWeek to get the numeric value for the day.
ShortDayNames[Index]; //Returns Fri
or
LongDayNames[Index]; //Returns Friday
The only way I know to shorten them to two chars would be to trim the resulting string
LeftStr(LongDayNames[Index],2);//Returns Fr
So today's Day would be
LeftStr(LongDayNames[DayOfWeek(date)],2); //Returns Fr
Click Here
Depicts the standards in custom date formatting.
You may also use the 'ddd' standard and trim it.
Delphi's routines does nothing special - they just ask OS.
Here is how to to it: Retrieving Time and Date Information. I looked through MSDNs docs and found this.
Note, that there is no really such thing as "2 character day-name" or "3 character day-name" here. There are: native ("long" in Delphi), abbreviated ("short" in Delphi) or short (Vista and above, not present in Delphi) formats.
For example, abbreviated name of the day of the week for Monday: Mon (3 chars, en-US), Пн (2 chars, ru-RU).
So, you probably look for LOCALE_SSHORTESTDAYNAMEX format (which is called "short" by MSDN and doesn't appear in Delphi), but it is availavle only on Vista and above.
For example, the following code:
const
LOCALE_SSHORTESTDAYNAME1 = $60;
procedure TForm1.Button1Click(Sender: TObject);
begin
SetThreadLocale($409);
ShowMessage(
GetLocaleStr(GetThreadLocale, LOCALE_SSHORTESTDAYNAME1, '') + #13#10 +
GetLocaleStr(GetThreadLocale, LOCALE_SABBREVDAYNAME1, '')
);
end;
will show you:
Mo
Mon
But doing this for Russian will output:
Пн
Пн
Hope my edits make answer more clear ;)