Index: /branches/release-33/lib/MT/DateTime.pm
===================================================================
--- /branches/release-33/lib/MT/DateTime.pm (revision 1174)
+++ /branches/release-33/lib/MT/DateTime.pm (revision 1744)
@@ -13,4 +13,6 @@
 use vars qw( @EXPORT_OK );
 @EXPORT_OK = qw( ymd2rd tz_offset_as_seconds );
+
+use MT::Util qw( epoch2ts );
 
 sub new {
@@ -170,4 +172,72 @@
 }
 
+sub _param2ts {
+    my ( $param, $blog ) = @_;
+
+    my ( $type, $value );
+    if ( 'HASH' eq ref($param) ) {
+        $type = $param->{type};
+        $value = $param->{value};
+    }
+    else {
+        $type = 'ts';
+        $value = $param;
+    }
+    if ( 'CODE' eq ref($value) ) {
+        $value = $value->();
+    }
+
+    my $ts;
+    if ( 'epoch' eq $type ) {
+        $ts = epoch2ts( $blog, $value );
+    }
+    elsif ( 'datetime' eq $type ) {
+        $ts = sprintf "%04d%02d%02d%02d%02d%02d",
+            $value->year,
+            $value->month,
+            $value->day,
+            $value->hour,
+            $value->minute,
+            $value->second;
+    }
+    else {
+        $ts = $value;
+    }
+    $ts;
+}
+
+sub compare {
+    my $self = shift;
+    my %param = @_;
+    # a => $ts | CODE | { value => CODE|$v, type => ts|epoch|datetime }
+    # b => $ts | CODE | { value => CODE|$v, type => ts|epoch|datetime }
+    # blog => ref|N|undef
+    # comparer => CODE|undef
+
+    my $blog = $param{blog};
+    if ( defined($blog) && !ref($blog) ) {
+        $blog = MT->model('blog')->load( $blog );
+        $blog = undef unless ref($blog);
+    }
+
+    if ( !exists($param{a}) && ref($self) ) {
+        $param{a} = { value => $self, type => 'datetime' };
+    }
+    my $ts_a = _param2ts( $param{a}, $blog );
+
+    if ( !exists($param{b}) && ref($self) ) {
+        $param{b} = { value => $self, type => 'datetime' };
+    }
+    my $ts_b = _param2ts( $param{b}, $blog );
+
+    my $comparer = $param{code};
+    if ( 'CODE' eq ref($comparer) ) {
+        return $comparer->( $ts_a, $ts_b );
+    }
+    else {
+        return $ts_a - $ts_b;
+    }
+}
+
 1;
 __END__
Index: /branches/release-33/lib/MT/AtomServer.pm
===================================================================
--- /branches/release-33/lib/MT/AtomServer.pm (revision 1174)
+++ /branches/release-33/lib/MT/AtomServer.pm (revision 1744)
@@ -557,9 +557,10 @@
     if (my $iso = $atom->issued) {
         my $pub_ts = MT::Util::iso2ts($blog, $iso);
-        my @ts = MT::Util::offset_time_list(time, $blog->id);
-        my $ts = sprintf '%04d%02d%02d%02d%02d%02d',
-            $ts[5]+1900, $ts[4]+1, @ts[3,2,1,0];
         $entry->authored_on($pub_ts);
-        if ($pub_ts > $ts) {
+        if ( 0 < MT::DateTime->compare( blog => $blog,
+                a => $pub_ts,
+                b => { value => time(), type => 'epoch' } )
+           )
+        {
             $entry->status(MT::Entry::FUTURE())
         }
@@ -647,9 +648,10 @@
     if (my $iso = $atom->issued) {
         my $pub_ts = MT::Util::iso2ts($blog, $iso);
-        my @ts = MT::Util::offset_time_list(time, $blog->id);
-        my $ts = sprintf '%04d%02d%02d%02d%02d%02d',
-            $ts[5]+1900, $ts[4]+1, @ts[3,2,1,0];
         $entry->authored_on($pub_ts);
-        if ($pub_ts > $ts) {
+        if ( 0 < MT::DateTime->compare( blog => $blog,
+                a => $pub_ts,
+                b => { value => time(), type => 'epoch' } )
+           )
+        {
             $entry->status(MT::Entry::FUTURE())
         }
Index: /branches/release-33/lib/MT/Util.pm
===================================================================
--- /branches/release-33/lib/MT/Util.pm (revision 1616)
+++ /branches/release-33/lib/MT/Util.pm (revision 1744)
@@ -119,5 +119,5 @@
 sub epoch2ts {
     my ($blog, $epoch) = @_;
-    $epoch = offset_time($epoch, $blog) if ref $blog;
+    $epoch = offset_time($epoch, $blog) if defined $blog;
     my ($s, $m, $h, $d, $mo, $y) = gmtime($epoch);
     sprintf("%04d%02d%02d%02d%02d%02d",
Index: /branches/release-33/lib/MT/XMLRPCServer.pm
===================================================================
--- /branches/release-33/lib/MT/XMLRPCServer.pm (revision 1724)
+++ /branches/release-33/lib/MT/XMLRPCServer.pm (revision 1744)
@@ -361,9 +361,10 @@
         $entry->authored_on(MT::XMLRPCServer::Util::iso2ts($blog, $iso))
             || die MT::XMLRPCServer::_fault(MT->translate("Invalid timestamp format"));
-        my @ts = MT::Util::offset_time_list(time, $blog_id);
-        my $ts = sprintf '%04d%02d%02d%02d%02d%02d',
-            $ts[5]+1900, $ts[4]+1, @ts[3,2,1,0];
+        require MT::DateTime;
         $entry->status(MT::Entry::FUTURE())
-            if ($entry->authored_on > $ts);
+            if MT::DateTime->compare(
+                blog => $blog,
+                a => $entry->authored_on,
+                b => { value => time(), type => 'epoch' } ) > 0;
     }
     $entry->discover_tb_from_entry();
@@ -487,4 +488,9 @@
         $entry->authored_on(MT::XMLRPCServer::Util::iso2ts($entry->blog_id, $iso))
            || die MT::XMLRPCServer::_fault(MT->translate("Invalid timestamp format"));
+        require MT::DateTime;
+        $entry->status(MT::Entry::FUTURE())
+            if MT::DateTime->compare(
+                a => $entry->authored_on,
+                b => { value => time(), type => 'epoch' } ) > 0;
     }
     $entry->discover_tb_from_entry();
Index: /branches/release-33/t/45-datetime.t
===================================================================
--- /branches/release-33/t/45-datetime.t (revision 1098)
+++ /branches/release-33/t/45-datetime.t (revision 1744)
@@ -24,5 +24,5 @@
 
 my $num_tests = 3;
-plan tests => (scalar @dates) * $num_tests;
+plan tests => 9 + (scalar @dates) * $num_tests;
 
 foreach my $dh (@dates) {
@@ -67,2 +67,23 @@
 }
 
+# compare tests
+my $t = time();
+ok( (MT::DateTime->compare( a => '20080401123456', b => '20080401123456' ) == 0), 'the same time is equal to each other');
+ok( (MT::DateTime->compare( a => '20080401123457', b => '20080401123456' ) > 0), 'a > b returns positive');
+ok( (MT::DateTime->compare( a => '20080401123456', b => '20080501123456' ) < 0), 'a < b returns negative');
+ok( (MT::DateTime->compare( a => { value => $t, type => 'epoch' }, b => { value => $t, type => 'epoch' } ) == 0), 'the same time is equal to each other');
+ok( (MT::DateTime->compare( b => { value => $t, type => 'epoch' }, a => { value => $t, type => 'epoch' } ) == 0), 'the same time is equal to each other');
+ok( (MT::DateTime->compare( b => { value => time(), type => 'epoch' }, a => '20080101235959' ) < 0), 'today is larger than Jan 1st 23:59:59, 2008');
+ok( (MT::DateTime->compare( a => { value => time(), type => 'epoch' }, b => '20080101235959' ) > 0), 'today is larger than Jan 1st 23:59:59, 2008');
+my $dt1 = MT::DateTime->new( %{$dates[0]} );
+my $dt2 = MT::DateTime->new( %{$dates[$#dates]} );
+ok( ($dt1->compare(a => { value => $dt2, type => 'datetime' }) > 0),
+    sprintf("%04d-%02d-%02d %02d:%02d:%02d %s", $dates[$#dates]{year}, $dates[$#dates]{month}, $dates[$#dates]{day}, $dates[$#dates]{hour}, $dates[$#dates]{minute}, $dates[$#dates]{second}, $dates[$#dates]{time_zone}) .
+    ' is the future from ' .
+    sprintf("%04d-%02d-%02d %02d:%02d:%02d %s", $dates[0]{year}, $dates[0]{month}, $dates[0]{day}, $dates[0]{hour}, $dates[0]{minute}, $dates[0]{second}, $dates[0]{time_zone})
+);
+ok( ($dt1->compare(b => { value => $dt2, type => 'datetime' }) < 0),
+    sprintf("%04d-%02d-%02d %02d:%02d:%02d %s", $dates[0]{year}, $dates[0]{month}, $dates[0]{day}, $dates[0]{hour}, $dates[0]{minute}, $dates[0]{second}, $dates[0]{time_zone}) .
+    ' is the past from ' .
+    sprintf("%04d-%02d-%02d %02d:%02d:%02d %s", $dates[$#dates]{year}, $dates[$#dates]{month}, $dates[$#dates]{day}, $dates[$#dates]{hour}, $dates[$#dates]{minute}, $dates[$#dates]{second}, $dates[$#dates]{time_zone})
+);
