<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><title type="text">WeirdLooking.com: Michael Barton's Blog</title><rights>Copyright 2006</rights><author><name>Michael Barton</name><email>palrich@gmail.com</email></author><updated>2010-09-07T14:05:51Z</updated><generator>WeirdLooking.com</generator><logo>http://www.weirdlooking.com/images/feed.png</logo><link rel="alternate" type="text/html" href="http://www.weirdlooking.com/" /><link rel="self" type="application/xml+atom" href="http://www.weirdlooking.com/atom/tag/computers%20and%20internet" /><id>http://www.weirdlooking.com/</id><entry><title type="text">barcode scanning</title><author><name>Michael Barton</name></author><link rel="alternate" type="text/html" href="http://www.weirdlooking.com/blog/barcode-scanning" /><id>http://www.weirdlooking.com/blog/barcode-scanning</id><published>2006-12-06T09:11:07Z</published><updated>2006-12-06T09:11:07Z</updated><content type="html">&lt;div style=&quot;float: right; margin: 2px; padding: 2px; border: solid 1px #555555;&quot;&gt;&lt;img src=&quot;http://www.weirdlooking.com/blog/81/scanner.png&quot; alt=&quot;some image&quot; /&gt;&lt;/div&gt;You may remember I was playing around with writing a Flash/webcam &lt;a href=&quot;http://www.weirdlooking.com/blog/62&quot; style=&quot;position: relative; padding-left: 8px; zoom: 1;&quot;&gt;&lt;span style=&quot;position: absolute; top: -5px; left: 0px; width: 16px; height: 16px; background: URL(http://www.weirdlooking.com/exticon?http%3A%2F%2Fwww.weirdlooking.com%2Fblog%2F62) no-repeat center center; -moz-opacity: 0.3; opacity: 0.3; filter:alpha(opacity=30);&quot;&gt;&lt;/span&gt;barcode scanner&lt;/a&gt; a while back.&amp;nbsp; Since nothing has ever come of that project, I decided I&amp;rsquo;d go ahead and stick it somewhere for a while with a &lt;a href=&quot;http://www.weirdlooking.com/BarcodeScanner/&quot; style=&quot;position: relative; padding-left: 8px; zoom: 1;&quot;&gt;&lt;span style=&quot;position: absolute; top: -5px; left: 0px; width: 16px; height: 16px; background: URL(http://www.weirdlooking.com/exticon?http%3A%2F%2Fwww.weirdlooking.com%2FBarcodeScanner%2F) no-repeat center center; -moz-opacity: 0.3; opacity: 0.3; filter:alpha(opacity=30);&quot;&gt;&lt;/span&gt;quick and dirty application&lt;/a&gt; I wrote in about a half hour (and it shows!).&lt;br /&gt;&lt;br /&gt;What happens is you scan a barcode, and it hits up Amazon for some information about the item via their &lt;a href=&quot;http://www.amazon.com/E-Commerce-Service-AWS-home-page/b/ref=sc_fe_l_2/105-7006971-8144447?ie=UTF8&amp;amp;node=12738641&amp;amp;no=3435361&amp;amp;me=A36L942TSJ2AJA&quot; style=&quot;position: relative; padding-left: 8px; zoom: 1;&quot;&gt;&lt;span style=&quot;position: absolute; top: -5px; left: 0px; width: 16px; height: 16px; background: URL(http://www.weirdlooking.com/exticon?http%3A%2F%2Fwww.amazon.com%2FE-Commerce-Service-AWS-home-page%2Fb%2Fref%3Dsc_fe_l_2%2F105-7006971-8144447%3Fie%3DUTF8%26amp%3Bnode%3D12738641%26amp%3Bno%3D3435361%26amp%3Bme%3DA36L942TSJ2AJA) no-repeat center center; -moz-opacity: 0.3; opacity: 0.3; filter:alpha(opacity=30);&quot;&gt;&lt;/span&gt;ECS&lt;/a&gt; webservice and displays it.&amp;nbsp; Their service returns a different XML format for each category, and I haven&amp;rsquo;t bothered to account for them all.&amp;nbsp; You&amp;rsquo;ll probably have the best luck scanning books and CDs.</content><category term="computers and internet" /><category term="flash" /><link rel="comments" type="application/atom+xml" href="http://www.weirdlooking.com/atom/comments/81" /><wfw:commentRss>http://www.weirdlooking.com/atom/comments/81</wfw:commentRss><slash:comments>0</slash:comments></entry><entry><title type="text">broken gmail feeds</title><author><name>Michael Barton</name></author><link rel="alternate" type="text/html" href="http://www.weirdlooking.com/blog/broken-gmail-feeds" /><id>http://www.weirdlooking.com/blog/broken-gmail-feeds</id><published>2006-09-04T18:53:29Z</published><updated>2006-09-04T18:53:29Z</updated><content type="html">Gmail provides Atom feeds of your inbox, but they come at a price.&amp;nbsp; And the price is the possibility of having to deal with them.&amp;nbsp; Mine kept causing an error in &lt;a href=&quot;http://www.rssbandit.org/&quot; style=&quot;position: relative; padding-left: 8px; zoom: 1;&quot;&gt;&lt;span style=&quot;position: absolute; top: -5px; left: 0px; width: 16px; height: 16px; background: URL(http://www.weirdlooking.com/exticon?http%3A%2F%2Fwww.rssbandit.org%2F) no-repeat center center; -moz-opacity: 0.3; opacity: 0.3; filter:alpha(opacity=30);&quot;&gt;&lt;/span&gt;RSS Bandit&lt;/a&gt;.&amp;nbsp; At first I tried to blame the aggregator, but then I took a closer look at the feed itself&amp;#8230;&lt;br /&gt;&lt;br /&gt;&lt;code style=&quot;display: block;&quot; class=&quot;blockocode&quot;&gt;&amp;lt;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;entry&lt;/span&gt;&amp;gt;&lt;br/&gt; &amp;nbsp;...&lt;br/&gt; &amp;nbsp;&amp;lt;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;modified&lt;/span&gt;&amp;gt;2006-09-03T24:56:06Z&amp;lt;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;/modified&lt;/span&gt;&amp;gt;&lt;br/&gt; &amp;nbsp;&amp;lt;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;issued&lt;/span&gt;&amp;gt;2006-09-03T24:56:06Z&amp;lt;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;/issued&lt;/span&gt;&amp;gt;&lt;br/&gt; &amp;nbsp;...&lt;br/&gt;&amp;lt;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;/entry&lt;/span&gt;&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;That email was received at nearly 25 o&amp;rsquo;clock, eh?&amp;nbsp; The interesting part is, it came in at 1am on the third (GMT).&amp;nbsp; &amp;nbsp; So not only is it an invalid date, it&amp;rsquo;s off by 24 hours.&amp;nbsp; I guess they just forgot to mod the hour by 24 or something.&lt;br /&gt;&lt;br /&gt;I submitted a bug to Google, and they promptly replied with an automated message!&amp;nbsp; It seems they aren&amp;rsquo;t able to respond directly to my report, but they are working on these issues.&amp;nbsp; I know I feel better about it ever getting fixed.&lt;br /&gt;&lt;br /&gt;So what I did was, I built myself a little proxy script that fixes the time.&amp;nbsp; I still need to make it pass through the cache headers, but I&amp;rsquo;m a bit lazy for that right now.&amp;nbsp; See, they&amp;rsquo;re &lt;span style=&quot;font-style: italic;&quot;&gt;forcing&lt;/span&gt; me to waste their bandwidth.&lt;br /&gt;&lt;br /&gt;&lt;code style=&quot;display: block;&quot; class=&quot;blockocode&quot;&gt;&amp;lt;?php&lt;br/&gt; &amp;nbsp;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;if&lt;/span&gt; (!isset($_SERVER[&lt;span style=&quot;color: #00B000&quot;&gt;'PHP_AUTH_USER'&lt;/span&gt;]))&lt;br/&gt; &amp;nbsp;{&lt;br/&gt; &amp;nbsp; &amp;nbsp;header(&lt;span style=&quot;color: #00B000&quot;&gt;'WWW-Authenticate: Basic realm=&quot;My Realm&quot;'&lt;/span&gt;);&lt;br/&gt; &amp;nbsp; &amp;nbsp;header(&lt;span style=&quot;color: #00B000&quot;&gt;'HTTP/1.0 401 Unauthorized'&lt;/span&gt;);&lt;br/&gt; &amp;nbsp; &amp;nbsp;echo &lt;span style=&quot;color: #00B000&quot;&gt;'You are NOT authorized.'&lt;/span&gt;;&lt;br/&gt; &amp;nbsp;}&lt;br/&gt; &amp;nbsp;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;else&lt;/span&gt;&lt;br/&gt; &amp;nbsp;{&lt;br/&gt; &amp;nbsp; &amp;nbsp;header(&lt;span style=&quot;color: #00B000&quot;&gt;'Content-type: text/xml'&lt;/span&gt;);&lt;br/&gt; &amp;nbsp; &amp;nbsp;$ch = curl_init(&lt;span style=&quot;color: #00B000&quot;&gt;&quot;https://mail.google.com/mail/feed/atom&quot;&lt;/span&gt;);&lt;br/&gt; &amp;nbsp; &amp;nbsp;curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, &lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;true&lt;/span&gt;);&lt;br/&gt; &amp;nbsp; &amp;nbsp;curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);&lt;br/&gt; &amp;nbsp; &amp;nbsp;curl_setopt($ch, CURLOPT_USERPWD, $_SERVER[&lt;span style=&quot;color: #00B000&quot;&gt;'PHP_AUTH_USER'&lt;/span&gt;].&lt;span style=&quot;color: #00B000&quot;&gt;':'&lt;/span&gt;.$_SERVER[&lt;span style=&quot;color: #00B000&quot;&gt;'PHP_AUTH_PW'&lt;/span&gt;]);&lt;br/&gt; &amp;nbsp; &amp;nbsp;curl_setopt($ch, CURLOPT_RETURNTRANSFER, &lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;true&lt;/span&gt;);&lt;br/&gt; &amp;nbsp; &amp;nbsp;echo preg_replace(&lt;span style=&quot;color: #00B000&quot;&gt;'/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z)/e'&lt;/span&gt;,&lt;br/&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #00B000&quot;&gt;'str_replace(\'T24:\', \'T01:\', \'$1\')'&lt;/span&gt;, curl_exec($ch));&lt;br/&gt; &amp;nbsp;}&lt;br/&gt;?&gt;&lt;/code&gt;</content><category term="computers and internet" /><category term="syndication" /><link rel="comments" type="application/atom+xml" href="http://www.weirdlooking.com/atom/comments/65" /><wfw:commentRss>http://www.weirdlooking.com/atom/comments/65</wfw:commentRss><slash:comments>0</slash:comments></entry><entry><title type="text">i hate actionscript</title><author><name>Michael Barton</name></author><link rel="alternate" type="text/html" href="http://www.weirdlooking.com/blog/i-hate-actionscript" /><id>http://www.weirdlooking.com/blog/i-hate-actionscript</id><published>2006-07-03T11:24:35Z</published><updated>2006-07-03T11:24:35Z</updated><content type="html">I needed to make a Flash movie containing pictures that could be dragged out onto the surrounding HTML elements.&amp;nbsp; And it almost worked, too.&lt;br /&gt;&lt;br /&gt;You can pass information from Flash to HTML by sending the browser to a javascript: URL, so the idea was to trap the mouse-down event in Flash, then pass a message to the javascript telling it that it&amp;rsquo;s currently in a dragging state.&amp;nbsp; Replicate the dragging graphic in both Flash and HTML, and you can almost imagine this method working.&lt;br /&gt;&lt;br /&gt;Except&amp;#8230; if you try to drag something outside of Flash, it refuses to give the mouse events back.&amp;nbsp; Flash continues receiving events though, so you could theoretically pass those back to the browser yourself.&amp;nbsp; But calling getURL(&amp;rsquo;javascript:&amp;#8230;&amp;rsquo;) to share the current mouse position causes IE to &amp;ldquo;click!&amp;rdquo; for every pixel the mouse moves.&lt;br /&gt;&lt;br /&gt;I&amp;rsquo;m not really a Flash guy, so this may be possible via some other chicanery.&amp;nbsp; But based on currently available data, I&amp;rsquo;m going to call it a defeat.&lt;br /&gt;&lt;br /&gt;Mike: 0, Flash: 1</content><category term="computers and internet" /><category term="actionscript" /><category term="javascript" /><link rel="comments" type="application/atom+xml" href="http://www.weirdlooking.com/atom/comments/61" /><wfw:commentRss>http://www.weirdlooking.com/atom/comments/61</wfw:commentRss><slash:comments>4</slash:comments></entry><entry><title type="text">javascript mud client 2</title><author><name>Michael Barton</name></author><link rel="alternate" type="text/html" href="http://www.weirdlooking.com/blog/javascript-mud-client-2" /><id>http://www.weirdlooking.com/blog/javascript-mud-client-2</id><published>2006-03-28T17:04:14Z</published><updated>2006-03-28T17:04:14Z</updated><content type="html">&lt;div style=&quot;float: right; margin: 2px; padding: 2px; border: solid 1px #555555;&quot;&gt;&lt;a href=&quot;//www.weirdlooking.com/blog/54/mudhtml.png&quot;&gt;&lt;img src=&quot;//www.weirdlooking.com/blog/54/mudhtml.png/200:*&quot; alt=&quot;Click to enlargen&quot; /&gt;&lt;/a&gt;&lt;/div&gt;I woke up early this morning and decided to start from scratch on my javascript mud client.&amp;nbsp; After writing the single worst implementation of a web server ever (it would have gone nicely with my networking final project, which included the single worst implementation of a web client ever), I was able to get it working.&lt;br /&gt;&lt;br /&gt;Basically, I rewrote the MUD to accept HTTP requests and wrap a javascript call around the output from each pulse.&amp;nbsp; Taking &lt;a href=&quot;http://www.muujware.com/matthew/&quot; style=&quot;position: relative; padding-left: 8px; zoom: 1;&quot;&gt;&lt;span style=&quot;position: absolute; top: -5px; left: 0px; width: 16px; height: 16px; background: URL(http://www.weirdlooking.com/exticon?http%3A%2F%2Fwww.muujware.com%2Fmatthew%2F) no-repeat center center; -moz-opacity: 0.3; opacity: 0.3; filter:alpha(opacity=30);&quot;&gt;&lt;/span&gt;Matt&lt;/a&gt;&amp;#39;s advice, I decided to use &amp;lt;b&amp;gt; tags with short class names, rather than the &amp;lt;span style=&amp;rdquo;color:&amp;#8230;&amp;rdquo;&amp;gt; stuff I was doing before.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Example (mud prompt)&lt;/span&gt;: &lt;code&gt;&amp;lt;script&amp;gt;parent.push('&amp;lt;br&amp;gt;&amp;lt;b class=g&amp;gt;&amp;amp;lt;20hp 100m 100mv&amp;amp;gt; &amp;lt;b class=X&amp;gt;');&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The browser downloads this &amp;ldquo;page&amp;rdquo; inside a hidden &amp;lt;iframe&amp;gt; (using the hack I &lt;a href=&quot;http://www.weirdlooking.com/blog/53&quot; style=&quot;position: relative; padding-left: 8px; zoom: 1;&quot;&gt;&lt;span style=&quot;position: absolute; top: -5px; left: 0px; width: 16px; height: 16px; background: URL(http://www.weirdlooking.com/exticon?http%3A%2F%2Fwww.weirdlooking.com%2Fblog%2F53) no-repeat center center; -moz-opacity: 0.3; opacity: 0.3; filter:alpha(opacity=30);&quot;&gt;&lt;/span&gt;previously posted&lt;/a&gt; for Internet Explorer, just a plain iframe for FF).&amp;nbsp; The push() function in the frame&amp;rsquo;s parent creates a new &amp;lt;pre&amp;gt; tag, stuffs the argument text inside it, then appends it to the display &amp;lt;div&amp;gt;.&amp;nbsp; Then the div&amp;rsquo;s scroll is set to the bottom.&lt;br /&gt;&lt;br /&gt;Mud input uses a form submit handler, which takes the value of the &amp;lt;input&amp;gt; and sticks it into an XMLHttpRequest, which is sent to the aforementioned worst web server implementation ever.&lt;br /&gt;&lt;br /&gt;I hacked it into &lt;a href=&quot;http://www.flugh.com/quickmud/&quot; style=&quot;position: relative; padding-left: 8px; zoom: 1;&quot;&gt;&lt;span style=&quot;position: absolute; top: -5px; left: 0px; width: 16px; height: 16px; background: URL(http://www.weirdlooking.com/exticon?http%3A%2F%2Fwww.flugh.com%2Fquickmud%2F) no-repeat center center; -moz-opacity: 0.3; opacity: 0.3; filter:alpha(opacity=30);&quot;&gt;&lt;/span&gt;QuickMUD&lt;/a&gt; rather than my own code base so that, should I ever decide to clean it up, other people can use it.&lt;br /&gt;&lt;br /&gt;Okay, so it&amp;rsquo;s pretty trivial.&amp;nbsp; But it was fun.</content><category term="computers and internet" /><category term="javascript" /><category term="mud" /><link rel="comments" type="application/atom+xml" href="http://www.weirdlooking.com/atom/comments/54" /><wfw:commentRss>http://www.weirdlooking.com/atom/comments/54</wfw:commentRss><slash:comments>7</slash:comments></entry><entry><title type="text">web-based mud client?</title><author><name>Michael Barton</name></author><link rel="alternate" type="text/html" href="http://www.weirdlooking.com/blog/web-based-mud-client" /><id>http://www.weirdlooking.com/blog/web-based-mud-client</id><published>2006-03-26T06:11:26Z</published><updated>2006-03-26T06:11:26Z</updated><content type="html">This blog post about Google&amp;rsquo;s web-based instant messaging is making the rounds:&lt;br /&gt;&lt;a href=&quot;http://alex.dojotoolkit.org/?p=538&quot; style=&quot;position: relative; padding-left: 8px; zoom: 1;&quot;&gt;&lt;span style=&quot;position: absolute; top: -5px; left: 0px; width: 16px; height: 16px; background: URL(http://www.weirdlooking.com/exticon?http%3A%2F%2Falex.dojotoolkit.org%2F%3Fp%3D538) no-repeat center center; -moz-opacity: 0.3; opacity: 0.3; filter:alpha(opacity=30);&quot;&gt;&lt;/span&gt;http://alex.dojotoolkit.org/?p=538&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So here&amp;rsquo;s my thinking&amp;#8230; If I can open up a second port on my &lt;a href=&quot;http://www.divineblood.org/&quot; style=&quot;position: relative; padding-left: 8px; zoom: 1;&quot;&gt;&lt;span style=&quot;position: absolute; top: -5px; left: 0px; width: 16px; height: 16px; background: URL(http://www.weirdlooking.com/exticon?http%3A%2F%2Fwww.divineblood.org%2F) no-repeat center center; -moz-opacity: 0.3; opacity: 0.3; filter:alpha(opacity=30);&quot;&gt;&lt;/span&gt;mud&lt;/a&gt; and run a simple HTTP server on it (lots of people have done this already), I can pretty easily hack write_to_descriptor to send information to a persistent HTTP connection.&amp;nbsp; In fact, it&amp;rsquo;ll practically be a regular mud connection except color codes and newlines and stuff will be parsed into their equivalent HTML (fairly straight-forward modification of the color code).&amp;nbsp; And interpret will be called from an HTTP post.&amp;nbsp; Then some work in javascript and I can have a web-based mud client.&lt;br /&gt;&lt;br /&gt;I&amp;rsquo;ll have the first &lt;a href=&quot;http://www.fuckweb2.com/&quot; style=&quot;position: relative; padding-left: 8px; zoom: 1;&quot;&gt;&lt;span style=&quot;position: absolute; top: -5px; left: 0px; width: 16px; height: 16px; background: URL(http://www.weirdlooking.com/exticon?http%3A%2F%2Fwww.fuckweb2.com%2F) no-repeat center center; -moz-opacity: 0.3; opacity: 0.3; filter:alpha(opacity=30);&quot;&gt;&lt;/span&gt;Web 2.0&lt;/a&gt; mud.</content><category term="computers and internet" /><category term="website" /><category term="javascript" /><link rel="comments" type="application/atom+xml" href="http://www.weirdlooking.com/atom/comments/53" /><wfw:commentRss>http://www.weirdlooking.com/atom/comments/53</wfw:commentRss><slash:comments>5</slash:comments></entry><entry><title type="text">i don't like (comment) spam!</title><author><name>Michael Barton</name></author><link rel="alternate" type="text/html" href="http://www.weirdlooking.com/blog/i-dont-like-comment-spam" /><id>http://www.weirdlooking.com/blog/i-dont-like-comment-spam</id><published>2005-12-23T06:06:20Z</published><updated>2005-12-23T06:06:20Z</updated><content type="html">You know, all of the comment spam is coming from the servers of Web hosting companies.&amp;nbsp; Which makes sense; they rarely monitor or charge for outgoing connections.&amp;nbsp; I assume that &lt;a href=&quot;http://www.weirdlooking.com/blog/4&quot; style=&quot;position: relative; padding-left: 8px; zoom: 1;&quot;&gt;&lt;span style=&quot;position: absolute; top: -5px; left: 0px; width: 16px; height: 16px; background: URL(http://www.weirdlooking.com/exticon?http%3A%2F%2Fwww.weirdlooking.com%2Fblog%2F4) no-repeat center center; -moz-opacity: 0.3; opacity: 0.3; filter:alpha(opacity=30);&quot;&gt;&lt;/span&gt;this page&lt;/a&gt; made its way into an automated comment spamming tool or something.&amp;nbsp; I&amp;rsquo;m going to delete most of that spam, I think.&amp;nbsp; Then I can remove the lame rel=&amp;rdquo;nofollow&amp;rdquo;s on comment links.&lt;br /&gt;&lt;br /&gt;As mentioned, I assume that this spam is posted by some sort of automated tool.&amp;nbsp; So, I have put an end to automated posting.&amp;nbsp; How, you ask?&amp;nbsp; I just hid one of those evil Unix timestamps in the form.&amp;nbsp; If you post a comment 30 minutes after that timestamp, it gives you an error (and a preview where you can click Submit again, so it&amp;rsquo;s not evil).&lt;br /&gt;&lt;br /&gt;Yeah, that&amp;rsquo;s easy to circumvent.&amp;nbsp; The form also includes a checksum of the time (generated via fantastic, super-secret cryptographic methods that you&amp;rsquo;ll never figure out, so don&amp;rsquo;t even bother trying).&amp;nbsp; The end result is that stale instances of the form, like those I assume live in a spammer&amp;rsquo;s database, won&amp;rsquo;t work.&lt;br /&gt;&lt;br /&gt;They could still easily download the page and scrape out a valid timestamp and checksum, but I think it&amp;rsquo;s probably enough for now to not be the low-hanging fruit.</content><category term="computers and internet" /><category term="spam" /><category term="website" /><link rel="comments" type="application/atom+xml" href="http://www.weirdlooking.com/atom/comments/46" /><wfw:commentRss>http://www.weirdlooking.com/atom/comments/46</wfw:commentRss><slash:comments>9</slash:comments></entry><entry><title type="text">human-readable date differences</title><author><name>Michael Barton</name></author><link rel="alternate" type="text/html" href="http://www.weirdlooking.com/blog/human-readable-date-differences" /><id>http://www.weirdlooking.com/blog/human-readable-date-differences</id><published>2005-12-21T11:29:32Z</published><updated>2005-12-21T11:29:32Z</updated><content type="html">I had an idea today.&amp;nbsp; I wanted to include human-readable ages beside some of the dates on my blog (e.g. &amp;ldquo;1 day, 8 hours ago&amp;rdquo;).&amp;nbsp; I searched around a bit, and all of the solutions I found just divide the difference in seconds by 31536000 to get years and so on.&amp;nbsp; It doesn&amp;rsquo;t take leap years or different-sized months into account.&lt;br /&gt;&lt;br /&gt;Today is December 21, 2005.&amp;nbsp; To me, 2 years, 2 months ago was October 21, 2003.&lt;br /&gt;&lt;br /&gt;It took a while to write.&amp;nbsp; The first version used brute force to get the difference out of &lt;a href=&quot;http://www.php.net/mktime&quot; style=&quot;position: relative; padding-left: 8px; zoom: 1;&quot;&gt;&lt;span style=&quot;position: absolute; top: -5px; left: 0px; width: 16px; height: 16px; background: URL(http://www.weirdlooking.com/exticon?http%3A%2F%2Fwww.php.net%2Fmktime) no-repeat center center; -moz-opacity: 0.3; opacity: 0.3; filter:alpha(opacity=30);&quot;&gt;&lt;/span&gt;mktime&lt;/a&gt;.&amp;nbsp; That worked perfectly but was slow.&amp;nbsp; I used it to generate a bunch of test cases, though.&lt;br /&gt;&lt;br /&gt;What I eventually figured out is that you can just subtract the beginning years, months, hours, etc. from the current ones.&amp;nbsp; After that, use borrowing similar to long subtraction to get rid of any negative numbers.&amp;nbsp; Seconds borrow 60 from a minute, hours borrow 24 from a day, days borrow from an array of month lengths.&amp;nbsp; You get the idea.&amp;nbsp; Anyway, here&amp;rsquo;s the code, which I&amp;rsquo;ll post on the &lt;a href=&quot;http://smarty.incutio.com/?page=SmartyPlugins&quot; style=&quot;position: relative; padding-left: 8px; zoom: 1;&quot;&gt;&lt;span style=&quot;position: absolute; top: -5px; left: 0px; width: 16px; height: 16px; background: URL(http://www.weirdlooking.com/exticon?http%3A%2F%2Fsmarty.incutio.com%2F%3Fpage%3DSmartyPlugins) no-repeat center center; -moz-opacity: 0.3; opacity: 0.3; filter:alpha(opacity=30);&quot;&gt;&lt;/span&gt;SmartyPlugins wiki&lt;/a&gt; as soon as I figure out how.&lt;br /&gt;&lt;br /&gt;&lt;code style=&quot;display: block;&quot; class=&quot;blockocode&quot;&gt;&amp;lt;?php&lt;br/&gt;&lt;br/&gt;&lt;span style=&quot;color: #00B000&quot;&gt;/**&lt;br/&gt; * Smarty plugin&lt;br/&gt; * -----------------------------------------&lt;br/&gt; * File: &amp;nbsp; &amp;nbsp;modifier.human_age.php&lt;br/&gt; * Type: &amp;nbsp; &amp;nbsp;modifier&lt;br/&gt; * Name: &amp;nbsp; &amp;nbsp;human_age&lt;br/&gt; * Params: &amp;nbsp;from_time &amp;nbsp; &amp;nbsp;unix timestamp (required)&lt;br/&gt; * &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;to_time &amp;nbsp; &amp;nbsp; &amp;nbsp;unix timestamp (default=false (means now))&lt;br/&gt; * &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;strip_zeroes remove units with zero values (&quot;0 days&quot;) (default=true)&lt;br/&gt; * &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;limit &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;limit the number of units returned (default=no limit)&lt;br/&gt; * Author: &amp;nbsp;Michael Barton (http://www.weirdlooking.com/email)&lt;br/&gt; * Purpose: Returns a human-readable difference between two times&lt;br/&gt; * &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;e.g. &quot;1 day, 8 hours, 48 minutes, 57 seconds&quot;&lt;br/&gt; * Remarks: Correct for leap years and different-sized months.&lt;br/&gt; * &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Well, my idea of correct. &amp;nbsp;Turns out it's slightly subjective.&lt;br/&gt; *&lt;br/&gt; * @link http://www.weirdlooking.com/blog/45&lt;br/&gt; * -----------------------------------------&lt;br/&gt; */&lt;/span&gt;&lt;br/&gt; &amp;nbsp;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;require_once&lt;/span&gt; $smarty-&gt;_get_plugin_filepath(&lt;span style=&quot;color: #00B000&quot;&gt;'shared'&lt;/span&gt;,&lt;span style=&quot;color: #00B000&quot;&gt;'make_timestamp'&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt; &amp;nbsp;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;function&lt;/span&gt; smarty_modifier_human_age($from_time, $to_time = &lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;false&lt;/span&gt;, $strip_zeroes = &lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;true&lt;/span&gt;, $limit = &lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;false&lt;/span&gt;)&lt;br/&gt; &amp;nbsp;{&lt;br/&gt; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;if&lt;/span&gt; ($to_time === &lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;false&lt;/span&gt;)&lt;br/&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;$to_time = time();&lt;br/&gt; &amp;nbsp; &amp;nbsp;$order = &lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;array&lt;/span&gt;(&lt;span style=&quot;color: #00B000&quot;&gt;'year'&lt;/span&gt;, &lt;span style=&quot;color: #00B000&quot;&gt;'mon'&lt;/span&gt;, &lt;span style=&quot;color: #00B000&quot;&gt;'mday'&lt;/span&gt;, &lt;span style=&quot;color: #00B000&quot;&gt;'hours'&lt;/span&gt;, &lt;span style=&quot;color: #00B000&quot;&gt;'minutes'&lt;/span&gt;, &lt;span style=&quot;color: #00B000&quot;&gt;'seconds'&lt;/span&gt;);&lt;br/&gt; &amp;nbsp; &amp;nbsp;$names = &lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;array&lt;/span&gt;(&lt;span style=&quot;color: #00B000&quot;&gt;'year'&lt;/span&gt;, &lt;span style=&quot;color: #00B000&quot;&gt;'month'&lt;/span&gt;, &lt;span style=&quot;color: #00B000&quot;&gt;'week'&lt;/span&gt;, &lt;span style=&quot;color: #00B000&quot;&gt;'day'&lt;/span&gt;, &lt;span style=&quot;color: #00B000&quot;&gt;'hour'&lt;/span&gt;, &lt;span style=&quot;color: #00B000&quot;&gt;'minute'&lt;/span&gt;, &lt;span style=&quot;color: #00B000&quot;&gt;'second'&lt;/span&gt;);&lt;br/&gt; &amp;nbsp; &amp;nbsp;$sizes = &lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;array&lt;/span&gt;(&lt;span style=&quot;color: #FF0000&quot;&gt;12&lt;/span&gt;, &lt;span style=&quot;color: #FF0000&quot;&gt;2&lt;/span&gt;=&gt;&lt;span style=&quot;color: #FF0000&quot;&gt;24&lt;/span&gt;, &lt;span style=&quot;color: #FF0000&quot;&gt;60&lt;/span&gt;, &lt;span style=&quot;color: #FF0000&quot;&gt;60&lt;/span&gt;);&lt;br/&gt; &amp;nbsp; &amp;nbsp;$month_lengths = &lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;array&lt;/span&gt;(&lt;span style=&quot;color: #FF0000&quot;&gt;31&lt;/span&gt;, &lt;span style=&quot;color: #FF0000&quot;&gt;31&lt;/span&gt;, &lt;span style=&quot;color: #FF0000&quot;&gt;28&lt;/span&gt;, &lt;span style=&quot;color: #FF0000&quot;&gt;31&lt;/span&gt;, &lt;span style=&quot;color: #FF0000&quot;&gt;30&lt;/span&gt;, &lt;span style=&quot;color: #FF0000&quot;&gt;31&lt;/span&gt;, &lt;span style=&quot;color: #FF0000&quot;&gt;30&lt;/span&gt;, &lt;span style=&quot;color: #FF0000&quot;&gt;31&lt;/span&gt;, &lt;span style=&quot;color: #FF0000&quot;&gt;31&lt;/span&gt;, &lt;span style=&quot;color: #FF0000&quot;&gt;30&lt;/span&gt;, &lt;span style=&quot;color: #FF0000&quot;&gt;31&lt;/span&gt;, &lt;span style=&quot;color: #FF0000&quot;&gt;30&lt;/span&gt;);&lt;br/&gt; &amp;nbsp; &amp;nbsp;$from = getdate($from_time);&lt;br/&gt; &amp;nbsp; &amp;nbsp;$to = getdate($to_time);&lt;br/&gt; &amp;nbsp; &amp;nbsp;$delta = &lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;array&lt;/span&gt;();&lt;br/&gt; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;foreach&lt;/span&gt; ($order &lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;as&lt;/span&gt; $unit)&lt;br/&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;$delta[] = $to[$unit] - $from[$unit];&lt;br/&gt; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;for&lt;/span&gt; ($i = &lt;span style=&quot;color: #FF0000&quot;&gt;5&lt;/span&gt;; $i &gt;= &lt;span style=&quot;color: #FF0000&quot;&gt;0&lt;/span&gt;; $i--)&lt;br/&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;if&lt;/span&gt; ($delta[$i] &amp;lt; &lt;span style=&quot;color: #FF0000&quot;&gt;0&lt;/span&gt;)&lt;br/&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br/&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$delta[$i-&lt;span style=&quot;color: #FF0000&quot;&gt;1&lt;/span&gt;]--;&lt;br/&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;if&lt;/span&gt; ($i == &lt;span style=&quot;color: #FF0000&quot;&gt;2&lt;/span&gt; &amp;amp;&amp;amp; ($to[&lt;span style=&quot;color: #00B000&quot;&gt;'mon'&lt;/span&gt;] == &lt;span style=&quot;color: #FF0000&quot;&gt;3&lt;/span&gt; &amp;amp;&amp;amp; !($to[&lt;span style=&quot;color: #00B000&quot;&gt;'year'&lt;/span&gt;] % &lt;span style=&quot;color: #FF0000&quot;&gt;4&lt;/span&gt;)))&lt;br/&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$delta[$i] += &lt;span style=&quot;color: #FF0000&quot;&gt;29&lt;/span&gt;; &lt;span style=&quot;color: #00B000&quot;&gt;// fix this before the year 2100!!!&lt;/span&gt;&lt;br/&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;if&lt;/span&gt; ($i == &lt;span style=&quot;color: #FF0000&quot;&gt;2&lt;/span&gt;)&lt;br/&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$delta[$i] += &amp;nbsp;$month_lengths[$to[&lt;span style=&quot;color: #00B000&quot;&gt;'mon'&lt;/span&gt;]-&lt;span style=&quot;color: #FF0000&quot;&gt;1&lt;/span&gt;];&lt;br/&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;else&lt;/span&gt;&lt;br/&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$delta[$i] += $sizes[$i-&lt;span style=&quot;color: #FF0000&quot;&gt;1&lt;/span&gt;];&lt;br/&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br/&gt; &amp;nbsp; &amp;nbsp;$delta[&lt;span style=&quot;color: #FF0000&quot;&gt;2&lt;/span&gt;] -= ($week = floor($delta[&lt;span style=&quot;color: #FF0000&quot;&gt;2&lt;/span&gt;]/&lt;span style=&quot;color: #FF0000&quot;&gt;7&lt;/span&gt;)) * &lt;span style=&quot;color: #FF0000&quot;&gt;7&lt;/span&gt;;&lt;br/&gt; &amp;nbsp; &amp;nbsp;$delta = &lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;array&lt;/span&gt;($delta[&lt;span style=&quot;color: #FF0000&quot;&gt;0&lt;/span&gt;], $delta[&lt;span style=&quot;color: #FF0000&quot;&gt;1&lt;/span&gt;], $week, $delta[&lt;span style=&quot;color: #FF0000&quot;&gt;2&lt;/span&gt;], $delta[&lt;span style=&quot;color: #FF0000&quot;&gt;3&lt;/span&gt;], $delta[&lt;span style=&quot;color: #FF0000&quot;&gt;4&lt;/span&gt;], $delta[&lt;span style=&quot;color: #FF0000&quot;&gt;5&lt;/span&gt;]);&lt;br/&gt; &amp;nbsp; &amp;nbsp;$ret = &lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;array&lt;/span&gt;();&lt;br/&gt; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;foreach&lt;/span&gt; ($delta &lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;as&lt;/span&gt; $i =&gt; $val)&lt;br/&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;if&lt;/span&gt; (($delta[$i] || !$strip_zeroes) &amp;amp;&amp;amp; ($limit === &lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;false&lt;/span&gt; || sizeof($ret) &amp;lt; $limit))&lt;br/&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$ret[] = $delta[$i].&lt;span style=&quot;color: #00B000&quot;&gt;' '&lt;/span&gt;.$names[$i].($delta[$i] == &lt;span style=&quot;color: #FF0000&quot;&gt;1&lt;/span&gt; ? &lt;span style=&quot;color: #00B000&quot;&gt;''&lt;/span&gt; : &lt;span style=&quot;color: #00B000&quot;&gt;'s'&lt;/span&gt;);&lt;br/&gt; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #0000B0; font-weight: bold;&quot;&gt;return&lt;/span&gt; join(&lt;span style=&quot;color: #00B000&quot;&gt;', '&lt;/span&gt;, $ret);&lt;br/&gt; &amp;nbsp;}&lt;br/&gt;?&gt;&lt;/code&gt;</content><category term="computers and internet" /><category term="php" /><category term="website" /><category term="smarty" /><link rel="comments" type="application/atom+xml" href="http://www.weirdlooking.com/atom/comments/45" /><wfw:commentRss>http://www.weirdlooking.com/atom/comments/45</wfw:commentRss><slash:comments>6</slash:comments></entry><entry><title type="text">mike:1 coldfusion: 0</title><author><name>Michael Barton</name></author><link rel="alternate" type="text/html" href="http://www.weirdlooking.com/blog/mike-1-coldfusion-0" /><id>http://www.weirdlooking.com/blog/mike-1-coldfusion-0</id><published>2005-12-20T01:58:49Z</published><updated>2005-12-20T01:58:49Z</updated><content type="html">&lt;a href=&quot;http://www.tallskinnywhiteguy.com/&quot; style=&quot;position: relative; padding-left: 8px; zoom: 1;&quot;&gt;&lt;span style=&quot;position: absolute; top: -5px; left: 0px; width: 16px; height: 16px; background: URL(http://www.weirdlooking.com/exticon?http%3A%2F%2Fwww.tallskinnywhiteguy.com%2F) no-repeat center center; -moz-opacity: 0.3; opacity: 0.3; filter:alpha(opacity=30);&quot;&gt;&lt;/span&gt;Cole&lt;/a&gt; mentioned that he was trying to parse Unix time stamps from Yahoo&amp;rsquo;s &lt;a href=&quot;http://developer.yahoo.net/traffic/rest/V1/index.html&quot; style=&quot;position: relative; padding-left: 8px; zoom: 1;&quot;&gt;&lt;span style=&quot;position: absolute; top: -5px; left: 0px; width: 16px; height: 16px; background: URL(http://www.weirdlooking.com/exticon?http%3A%2F%2Fdeveloper.yahoo.net%2Ftraffic%2Frest%2FV1%2Findex.html) no-repeat center center; -moz-opacity: 0.3; opacity: 0.3; filter:alpha(opacity=30);&quot;&gt;&lt;/span&gt;traffic web services&lt;/a&gt; to something human-readable.&amp;nbsp; In &lt;a href=&quot;http://www.macromedia.com/software/coldfusion/&quot; style=&quot;position: relative; padding-left: 8px; zoom: 1;&quot;&gt;&lt;span style=&quot;position: absolute; top: -5px; left: 0px; width: 16px; height: 16px; background: URL(http://www.weirdlooking.com/exticon?http%3A%2F%2Fwww.macromedia.com%2Fsoftware%2Fcoldfusion%2F) no-repeat center center; -moz-opacity: 0.3; opacity: 0.3; filter:alpha(opacity=30);&quot;&gt;&lt;/span&gt;ColdFusion&lt;/a&gt;.&amp;nbsp; In case you don&amp;rsquo;t know, CF runs on top of Java and has access to its entire API.&amp;nbsp; &amp;ldquo;Easy&amp;rdquo;, thought I, Java&amp;rsquo;s Date object can deal with milliseconds since epoch, very similar to your Unix time stamps in most regards.&amp;nbsp; ColdFusion&amp;rsquo;s DateFormat function can then be used to translate Date objects into a human-readable string.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;cfset time = 1135038970&amp;gt;&lt;br /&gt;&amp;lt;cfset date = createObject(&amp;quot;java&amp;quot;, &amp;quot;java.util.Date&amp;quot;).init(time * 1000)&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Nope.&amp;nbsp; The constructor takes a long argument and coldfusion&amp;rsquo;s scalars cast to doubles when sent to java.&amp;nbsp; So we turn to ColdFusion&amp;rsquo;s answer, JavaCast.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;cfset date = createObject(&amp;quot;java&amp;quot;, &amp;quot;java.util.Date&amp;quot;).init(JavaCast(&amp;quot;long&amp;quot;, time * 1000))&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This is where it got weird.&amp;nbsp; Coldfusion threw an error that the number was too big to be cast to an int.&amp;nbsp; What?!&amp;nbsp; Why is it casting anything to an int?!&lt;br /&gt;I tried a slight variation:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;cfset date = createObject(&amp;quot;java&amp;quot;, &amp;quot;java.util.Date&amp;quot;).init(JavaCast(&amp;quot;long&amp;quot;, time) * 1000)&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;It cast time to a long alright, but then multiplying it by 1000 casts it back to a double.&amp;nbsp; So I wracked my brain for a way to get this number multiplied by 1000 into a long.&amp;nbsp; Laughing maniacally, I typed it out:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;cfset date = createObject(&amp;quot;java&amp;quot;, &amp;quot;java.util.Date&amp;quot;).init(createObject(&amp;quot;java&amp;quot;, &amp;quot;java.lang.Long&amp;quot;).parseLong(time &amp;amp; &amp;quot;000&amp;quot;))&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;You proved a worthy adversary, ColdFusion, but your crane style was no match for my tiger style.&lt;br /&gt;Oh, and there you go, Cole. :D</content><category term="computers and internet" /><category term="coldfusion" /><link rel="comments" type="application/atom+xml" href="http://www.weirdlooking.com/atom/comments/44" /><wfw:commentRss>http://www.weirdlooking.com/atom/comments/44</wfw:commentRss><slash:comments>6</slash:comments></entry></feed>