Jump to content

comparing dates


Loriot

Recommended Posts

Hi all,I am trying to compare some dates but did not find the correct syntax until now.In the XML I find time tags like that

<Time_1>YYYY-MM-DD hh:mm:ss.msec</Time_1> <Time_2>YYYY-MM-DD hh:mm:ss.msec</Time_2>

Now I try to pick elements that have Time_1 < Time_2. I tried the following, but they don't work.

<xsl:if test="dateTime(Time_1) < dateTime(Time_2)"><xsl:if test="Time_1 < Time_2"><xsl:if test="number(Time_1) < number(Time_2)">

Could you give me a hint?Thanx in advanceLoriot

Link to comment
Share on other sites

The date and time functions are part of XPath 2. Thus, they are not supported in any browser yet. The only way I know you can do it now is with the substring() function, but considering the large amount of data to be compared, this would take a lot of substing() to complete.

Link to comment
Share on other sites

You mean you're not only going to compare date numbers but also strings (month names perhaps?)?!?! This makes it double harder. You have to assign each month's substring to a number and compare that number instead.... It's all waaay too complicated. Dividing your dates into elements or attributes would make it a bit easier:

<date><day>1</day><month>2</month><year>2006</year></date><time><second>34<second><minutes>13</minutes><hours>16</hours></time>

Link to comment
Share on other sites

No, that won't help. Other idea: My < comparing could probably work on numbers if I just get transformed the time.so if I take the substring hh.mm.ss.msec and transform it all to msec, then I can compare the numbers with <I am just not good eneough in this xsl:call-template xsl:with-param thing to get an idea how this calculation could be done. Have you?

Link to comment
Share on other sites

Comparing the substrings one by one would be simpler then transforming them and comparing the results. For example, you would first check which year is more recent. If an year is, then it's sure the whole date is. If they're equial, compare the months and so on. If you want to sort multiple elements according to their date, you must divide your date and time in a manner simmilar to what I showed in my previous post and apply multiple <xsl:sort> for each element. I'm just not into codewriting right now, but I hope you get my idea.

Link to comment
Share on other sites

It seems to turn out working with a not yet completed combination of that

<xsl:if test="number(substring(Time_1,12,2)) >= number(substring(Time_2,12,2)">

I get back with the complete solution after I combined it corectly.Thanx for the moment for being inspiering!

Link to comment
Share on other sites

Hi again,I found a working solution now, but I have to do a double processing, so maybe you know something more elegant. If so: Please let me know!But: My solution works and here it comes.The original XML:

<MainRoot>	<Time_1>yyyy-mm-dd hh:mm:ss.msec</Time_1>	<Track>		<Element>		  <Time_2>yyyy-mm-dd hh:mm:ss.msec<Time_2>		  <Title>Title</Title>		</Element>		<Element>		  <Time_2>yyyy-mm-dd hh:mm:ss.msec<Time_2>		  <Title>other Title</Title>		</Element>	</Track></MainRoot>

The first Stylesheet looks like that:

<?xml version="1.0"?><xsl:stylesheet version= "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/">   <xsl:variable name="Time_1">	<xsl:value-of select="substring(Time_1,1,4)" />	<xsl:value-of select="substring(Time_1,6,2)" />	<xsl:value-of select="substring(Time_1,9,2)" /> 	<xsl:value-of select="substring(Time_1,12,2)" />	<xsl:value-of select="substring(Time_1,15,2)" />	<xsl:value-of select="substring(Time_1,18,2)" />  </xsl:variable>   <MainRoot>	<xsl:for-each select="/Track/Element[Class='Music']">	<Element>		<Time_1><xsl:copy-of select="$Time_1" /></Time_1>		<Time_2><xsl:value-of select="substring(Time_2,1,4)" />			<xsl:value-of select="substring(Time_2,6,2)" />			<xsl:value-of select="substring(Time_2,9,2)" /> 			<xsl:value-of select="substring(Time_2,12,2)" />			<xsl:value-of select="substring(Time_2,15,2)" />			<xsl:value-of select="substring(Time_2,18,2)" /><Time_2>		<Title><xsl:value-of select="Title"/></Title>		</Element>   <MainRoot>		</xsl:for-each></xsl:template></xsl:stylesheet>

This delivers an XML file with comparable numbers as Times looking like yyyymmddhhmmssmsecThe result XML file is then processed with another stylesheet doing that:

<xsl:if test="number(Time_1) <= number(Time_2)"></xsl:if>

Is there a way to do this in one step?RegardsLoriot

Link to comment
Share on other sites

I think the translate() function can search&replace characters, so something like:

 <xsl:variable name="time" select="MainRoot/Time_1"/><xsl:value-of select="translate($time,:-. ,)"/>

might help with that.

Link to comment
Share on other sites

Maybe if both times are in their own variables and you then compare those vairables...

 <xsl:variable name="time1" select="MainRoot/Time_1"/><xsl:variable name="new-time1"><xsl:value-of select="translate($time,:-. ,)"/></xsl:variable><xsl:variable name="time2" select="MainRoot/Track/Element/Time_2"/><xsl:variable name="new-time2"><xsl:value-of select="translate($time2,:-. ,)"/></xsl:variable><xsl:if test="new-time1 < new-time2">...</xsl:if>

Of course, that's just a concept. Comparing large amounts of dates would requre something just a bit more creative.

Link to comment
Share on other sites

I had tried that already but it didn't work :-( The problem is, that I don't have the times on the same level. So my workaround is all about copyieng the root value into the element values and have in the second step an if test on values on (now) same level. So this is the challenge I don't get into one stylesheet

Link to comment
Share on other sites

Hi again,I just wanted to post, that I finally found a solution to do the transformation in one step and I wanted to let you know. The XML is still teh one I posted a litlle further up. Here comes my stylesheet:

<?xml version="1.0"?><xsl:stylesheet version= "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:variable name="time_1" select="translate(substring(MainRoot/Time_1,12,8),'- :.','')" /><MainRoot><ShowStart><xsl:value-of select="MainRoot/Time_1"/></ShowStart><xsl:for-each select="MainRoot/Track//Element"><xsl:variable name="time_2" select="translate(substring(Time_2,11,9),'::','')" />	<xsl:if test="number($time_1) <= number($time_2)">		<Element>			<xsl:value-of select="tag1" />			<xsl:value-of select="tag2"/>		</Element>	</xsl:if></xsl:for-each></MainRoot></xsl:template></xsl:stylesheet>

So now I get only results from the elements with a time_2 being after the time_1 :) Have fun with that!!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...