{"id":66853,"date":"2006-07-21T14:55:00","date_gmt":"2006-07-21T14:55:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2006\/07\/21\/how-can-i-subtract-a-specified-number-of-days-from-a-utc-value\/"},"modified":"2006-07-21T14:55:00","modified_gmt":"2006-07-21T14:55:00","slug":"how-can-i-subtract-a-specified-number-of-days-from-a-utc-value","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-subtract-a-specified-number-of-days-from-a-utc-value\/","title":{"rendered":"How Can I Subtract a Specified Number of Days from a UTC Value?"},"content":{"rendered":"<p><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" height=\"34\" alt=\"Hey, Scripting Guy! Question\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\"> \n<P>Hey, Scripting Guy! Suppose I get a date-time value in UTC format. How can I subtract <I>x<\/I> number of days from that value?<BR><BR>&#8212; MW<\/P><IMG height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" height=\"34\" alt=\"Hey, Scripting Guy! Answer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><IMG class=\"farGraphic\" title=\"Script Center\" height=\"288\" alt=\"Script Center\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" align=\"right\" border=\"0\"><\/A> \n<P>Hey, MW. First of all, we\u2019d like to thank you for your question; in addition, we\u2019d like to welcome you and everyone else to today\u2019s <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/postcards\/default.mspx\"><B>Open House<\/B><\/A> in honor of the 500<SUP>th <\/SUP><I>Hey, Scripting Guy!<\/I> column. We know that a few of you are wondering why we\u2019re so excited about the 500<SUP>th<\/SUP> column; isn\u2019t 500 just another number? Well, to be honest, we\u2019re pretty proud of this achievement. In fact, the consensus among the Scripting Guys is that producing 500 daily columns on system administration scripting just might be the greatest feat in literary history.<\/P>\n<P>But don\u2019t take our word for it. Let\u2019s check the mail and see what some of our loyal readers have to say about this:<\/P>\n<TABLE class=\"dataTable\" id=\"EOD\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P>Hey, Scripting Guy! Congratulations on column number 500; that\u2019s pretty good. But did you know that a South African novelist named Mary Faulkner wrote 904 <I>books<\/I> in her lifetime? Now <I>that\u2019s<\/I> impressive.<\/P>\n<P>&#8212; RS<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Um, no, RS, we didn\u2019t know about Mary Faulkner. But, then again, we write about scripting, you know, highly-technical stuff. Mary Faulkner was a novelist; how hard could it be to write 904 novels?<\/P>\n<P>Let\u2019s try another letter:<\/P>\n<TABLE class=\"dataTable\" id=\"EAE\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P>Hey, Scripting Guy! Wow: 500 columns, and all of them on highly-technical stuff like scripting. Congratulations; I can\u2019t think of anyone who\u2019s been able to top that achievement.<\/P>\n<P>Well, OK, maybe Isaac Asimov. Did you know that, in addition to 463 books, he wrote over 1600 full-length essays on highly-technical topics? In fact, Asimov is the only writer to have published books that encompass all 10 of the major Dewey Decimal categories. On top of that, he wrote an estimated 90,000 letters and postcards during his lifetime!<\/P>\n<P>&#8212; SB<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Gee, that\u2019s \u2026 great; good for him. Let\u2019s try one more:<\/P>\n<TABLE class=\"dataTable\" id=\"ELE\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P>Hey, Scripting Guy! Although everyone is focusing on the 500<SUP>th<\/SUP> column, I happened to notice that you guys are approaching your second anniversary (August 2, 2006 to be exact). Wow: writing a column every day for the past two years is really something. Did anyone ever tell you that Dear Abby wrote her column every day for <I>46<\/I> years, from 1956 through 2002?<\/P>\n<P>&#8212; CM<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>You know, rather than spend any more time on letters maybe we should get right to today\u2019s question. <\/P>\n<P>By the way, what <I>is<\/I> today\u2019s question?<\/P>\n<P>Oh, that\u2019s right: subtracting <I>x<\/I> number of days from a UTC date-time value. For those of you who aren\u2019t familiar with the term, UTC is short of Universal Time Coordinate; when you get a UTC value (as you often will when working with WMI) you end up with a date that looks something like this:<\/P><PRE class=\"codeSample\">20060720132442.000000-420\n<\/PRE>\n<TABLE class=\"dataTable\" id=\"EHF\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\"><B>Note<\/B>. True. But many of us have had dates that looked even <I>scarier<\/I> than that. And a few of us <I>were<\/I> the dates that looked even scarier than that.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>We won\u2019t bother explaining how to decipher this value; if you have a burning desire to know how to do that then take a peek at the <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/guide\/sas_wmi_fvwp.mspx\" target=\"_blank\"><B>Microsoft Windows 2000 Scripting Guide<\/B><\/A>. Instead, let\u2019s focus on the topic at hand, subtracting a specified number of days from this UTC value. How do we do that? To tell you the truth, we have no idea.<\/P>\n<P>But that\u2019s OK: if we can\u2019t subtract a specified number of days from our UTC value then we\u2019ll simply turn that UTC value into something that we <I>can<\/I> subtract a specified number of days from. What we\u2019re going to do is convert the UTC value into a regular date-time value, subtract the desired number of days, and then convert the answer back to a UTC value. This will have the desired effect, and no one will ever know that we cheated:<\/P><PRE class=\"codeSample\">Const CONVERT_TO_LOCAL_TIME = True<\/p>\n<p>Set dtmStart = CreateObject(&#8220;WbemScripting.SWbemDateTime&#8221;)\ndtmStart.SetVarDate Now, CONVERT_TO_LOCAL_TIME\nWscript.Echo dtmStart<\/p>\n<p>dtmRegular = dtmStart.GetVarDate(CONVERT_TO_LOCAL_TIME)\nWscript.Echo dtmRegular<\/p>\n<p>dtmNew = DateAdd(&#8220;d&#8221;, -37, dtmRegular)\nWscript.Echo dtmNew<\/p>\n<p>Set dtmEnd = CreateObject(&#8220;WbemScripting.SWbemDateTime&#8221;)\ndtmEnd.SetVarDate dtmNew, CONVERT_TO_LOCAL_TIME\nWscript.Echo dtmEnd\n<\/PRE>\n<P>A couple of notes here. First, we opted to use the SWbemDateTime object for this script. The good news is that this makes it very easy to switch back and forth between UTC dates and regular dates. The bad news? This limits this script to working on Windows XP and Windows Server 2003. Could we modify this script to work on, say, Windows 2000? Yes, but there\u2019s quite a bit of explanation involved in doing so. For now we\u2019ll stick with this version; if anyone needs a Windows 2000 version let us know and we\u2019ll see what we can come up with.<\/P>\n<TABLE class=\"dataTable\" id=\"EHG\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\"><B>Note<\/B>. In the meantime, you can find functions for converting between date-time formats <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/guide\/sas_wmi_yakv.mspx\" target=\"_blank\"><B>here<\/B><\/A>. Oh: and over <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/guide\/sas_wmi_onfu.mspx\" target=\"_blank\"><B>here<\/B><\/A>, too.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Second, we should also point out that the script is a tiny bit longer than it needs to be. That\u2019s because we periodically pause for a moment and echo back a date-time value; we do that simply so you can watch what happens as we switch from one format to another. That seemed a little more educational, and we Scripting Guys are all about education. Along the same lines, we create an extra variable or two, just so you don\u2019t get confused as to which variable is holding which information.<\/P>\n<P>Unlike people (and we aren\u2019t mentioning any names, Mary Faulkner) who just like to show off how prolific they are. Besides, if you add up all the books the Scripting Guys have written, well, we\u2019re only 903 behind Ms. Faulkner. We\u2019re right behind you and gaining fast, Mary!<\/P>\n<P>But back to the script. We start out by defining a constant named CONVERT_TO_LOCAL_TIME and setting the value to True; we\u2019ll use this constant to tell the SWbemDateTime object that we want to convert our date-time value to local time (as opposed to Greenwich Mean Time).<\/P>\n<TABLE class=\"dataTable\" id=\"EBH\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\"><B>Note<\/B>. You know, we never thought about this before, but if you live in Greenwich, England it probably doesn\u2019t matter whether you convert to local time or not. The Scripting Guy who writes this column was actually <I>in<\/I> Greenwich, England last summer. Oddly enough, he never once thought about UTC date-time values while he was there. Go figure.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>After defining the constant we create an instance of the <B>WbemScripting.SWbemDateTime<\/B> object, then call the <B>SetVarDate<\/B> method to convert the current date and time to a UTC date-time value:<\/P><PRE class=\"codeSample\">dtmStart.SetVarDate Now, CONVERT_TO_LOCAL_TIME\n<\/PRE>\n<P>Notice that we pass SetVarDate two parameters: the date-time value to be converted, and the constant CONVERT_TO_LOCAL_TIME. We then echo back the date-time value we just created, a value that should look something like this:<\/P><PRE class=\"codeSample\">20060720134533.000000-420\n<\/PRE>\n<P>Of course, now that we have a UTC value we want to get rid of it; we\u2019ve already decided that we don\u2019t know how to subtract <I>x<\/I> number of days from something like that. Therefore, we take the object reference dtmStart and call the <B>GetVarDate<\/B> method:<\/P><PRE class=\"codeSample\">dtmRegular = dtmStart.GetVarDate(CONVERT_TO_LOCAL_TIME)\n<\/PRE>\n<P>This simply converts our UTC value back to a more human-friendly date-time value, a value we store in a variable named dtmRegular. We then echo back the value of dtmRegular, which should look similar to this:<\/P><PRE class=\"codeSample\">7\/20\/2006 1:45:33 PM\n<\/PRE>\n<P>Still with us? Good. Now that we have a \u201creal\u201d date and time to work with we can use VBScript\u2019s <B>DateAdd<\/B> method to subtract a specified number of days (say, 37) from that value. That\u2019s what we do here:<\/P><PRE class=\"codeSample\">dtmNew = DateAdd(&#8220;d&#8221;, -37, dtmRegular)\n<\/PRE>\n<P>As you can see, this isn\u2019t especially complicated. We simply call DateAdd, passing it three parameters:<\/P>\n<TABLE class=\"\" cellSpacing=\"0\" cellPadding=\"0\" border=\"0\">\n<TBODY>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>\u201cd\u201d<\/B>, which tells the function to work with days as the unit of measure. (As opposed to hours, minutes, years, etc. For a complete list of allowed units see the <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/guide\/sas_vbs_ufbq.mspx\" target=\"_blank\"><B>Scripting Guide<\/B><\/A>.)<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>-37<\/B>, the number of days to subtract. If we wanted to <I>add<\/I> 37 days we\u2019d simply leave off the minus sign.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>dtmRegular<\/B>, the variable containing our base date, the date we\u2019re going to add our subtract time from.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>The results of this function get stored in yet <I>another<\/I> variable (dtmNew), a variable which will contain a value similar to this:<\/P><PRE class=\"codeSample\">6\/13\/2006 1:45:33 PM\n<\/PRE>\n<P>And there you go: June 13, 2006 occurred 37 days prior to July 20, 2006. Not bad, huh?<\/P>\n<P>Just for the heck of it, we then convert the June 13<SUP>th<\/SUP> value <I>back<\/I> to a UTC value. That\u2019s what this line of code does:<\/P><PRE class=\"codeSample\">dtmEnd.SetVarDate dtmNew, CONVERT_TO_LOCAL_TIME\n<\/PRE>\n<P>In turn, that gives us a UTC value just like this one:<\/P><PRE class=\"codeSample\">20060613134533.000000-420\n<\/PRE>\n<P>The circle of life is complete.<\/P>\n<P>If you\u2019d just as soon forego all that echoing of intermediate stages along the way, well, here\u2019s a condensed script that simply reports back the desired date and time in UTC format:<\/P><PRE class=\"codeSample\">Const CONVERT_TO_LOCAL_TIME = True<\/p>\n<p>Set dtmStart = CreateObject(&#8220;WbemScripting.SWbemDateTime&#8221;)\ndtmStart.SetVarDate Now, CONVERT_TO_LOCAL_TIME\ndtmRegular = dtmStart.GetVarDate(CONVERT_TO_LOCAL_TIME)\ndtmRegular = DateAdd(&#8220;d&#8221;, -37, dtmRegular)\ndtmStart.SetVarDate dtmRegular, CONVERT_TO_LOCAL_TIME<\/p>\n<p>Wscript.Echo dtmStart\n<\/PRE>\n<P>There you have it, MW: column number 500 is officially in the books. Just think: 1,101 more and we can claim to have passed Isaac Asimov. And then, 54 years from now, we\u2019ll set our sights on Dear Abby.<\/P>\n<P>You know, on second thought, maybe we\u2019ll just try and catch Isaac Asimov and then call it good. You win, Dear Abby: you beat us fair and square.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! Suppose I get a date-time value in UTC format. How can I subtract x number of days from that value?&#8212; MW Hey, MW. First of all, we\u2019d like to thank you for your question; in addition, we\u2019d like to welcome you and everyone else to today\u2019s Open House in honor of the [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[13,3,4,5],"class_list":["post-66853","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-dates-and-times","tag-scripting-guy","tag-scripting-techniques","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! Suppose I get a date-time value in UTC format. How can I subtract x number of days from that value?&#8212; MW Hey, MW. First of all, we\u2019d like to thank you for your question; in addition, we\u2019d like to welcome you and everyone else to today\u2019s Open House in honor of the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/66853","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=66853"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/66853\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=66853"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=66853"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=66853"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}