The R Project SVN R

Rev

Rev 27975 | Rev 29378 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 27975 Rev 28072
Line 719... Line 719...
719
    SET_STRING_ELT(class, 1, mkChar("POSIXlt"));
719
    SET_STRING_ELT(class, 1, mkChar("POSIXlt"));
720
    classgets(ans, class);
720
    classgets(ans, class);
721
    UNPROTECT(3);
721
    UNPROTECT(3);
722
    return ans;
722
    return ans;
723
}
723
}
-
 
724
 
-
 
725
SEXP do_D2POSIXlt(SEXP call, SEXP op, SEXP args, SEXP env)
-
 
726
{
-
 
727
    SEXP x, ans, ansnames, class;
-
 
728
    int n, i, valid;
-
 
729
    long day;
-
 
730
    int y, tmp, mon;
-
 
731
    struct tm tm;
-
 
732
 
-
 
733
    checkArity(op, args);
-
 
734
    PROTECT(x = coerceVector(CAR(args), REALSXP));
-
 
735
    n = LENGTH(x);
-
 
736
    PROTECT(ans = allocVector(VECSXP, 9));
-
 
737
    for(i = 0; i < 9; i++)
-
 
738
	SET_VECTOR_ELT(ans, i, allocVector(INTSXP, n));
-
 
739
 
-
 
740
    PROTECT(ansnames = allocVector(STRSXP, 9));
-
 
741
    for(i = 0; i < 9; i++)
-
 
742
	SET_STRING_ELT(ansnames, i, mkChar(ltnames[i]));
-
 
743
 
-
 
744
    for(i = 0; i < n; i++) {
-
 
745
	if(R_FINITE(REAL(x)[i])) {
-
 
746
	    day = (long) REAL(x)[i];
-
 
747
	    tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
-
 
748
	    /* weekday: 1970-01-01 was a Thursday */
-
 
749
	    if ((tm.tm_wday = ((4 + day) % 7)) < 0) tm.tm_wday += 7;
-
 
750
 
-
 
751
	    /* year & day within year */
-
 
752
	    y = 1970;
-
 
753
	    if (day >= 0)
-
 
754
		for ( ; day >= (tmp = days_in_year(y)); day -= tmp, y++);
-
 
755
	    else
-
 
756
		for ( ; day < 0; --y, day += days_in_year(y) );
-
 
757
	    
-
 
758
	    y = tm.tm_year = y - 1900;
-
 
759
	    tm.tm_yday = day;
-
 
760
 
-
 
761
	    /* month within year */
-
 
762
	    for (mon = 0;
-
 
763
		 day >= (tmp = (days_in_month[mon]) + 
-
 
764
			 ((mon==1 && isleap(y+1900))?1:0));
-
 
765
		 day -= tmp, mon++);
-
 
766
	    tm.tm_mon = mon;
-
 
767
	    tm.tm_mday = day + 1;
-
 
768
	    tm.tm_isdst = 0; /* no dst in GMT */
-
 
769
 
-
 
770
	    valid = 1;
-
 
771
	} else valid = 0;
-
 
772
	makelt(&tm, ans, i, valid);
-
 
773
    }
-
 
774
    setAttrib(ans, R_NamesSymbol, ansnames);
-
 
775
    PROTECT(class = allocVector(STRSXP, 2));
-
 
776
    SET_STRING_ELT(class, 0, mkChar("POSIXt"));
-
 
777
    SET_STRING_ELT(class, 1, mkChar("POSIXlt"));
-
 
778
    classgets(ans, class);
-
 
779
    UNPROTECT(4);
-
 
780
 
-
 
781
    return ans;
-
 
782
}
-
 
783
 
-
 
784
SEXP do_POSIXlt2D(SEXP call, SEXP op, SEXP args, SEXP env)
-
 
785
{
-
 
786
    SEXP x, ans, class;
-
 
787
    int i, n = 0, nlen[9];
-
 
788
    struct tm tm;
-
 
789
 
-
 
790
    checkArity(op, args);
-
 
791
    x = CAR(args);
-
 
792
    if(!isVectorList(x) || LENGTH(x) != 9)
-
 
793
	error("invalid `x' argument");
-
 
794
 
-
 
795
    for(i = 3; i < 6; i++)
-
 
796
	if((nlen[i] = LENGTH(VECTOR_ELT(x, i))) > n) n = nlen[i];
-
 
797
    if((nlen[8] = LENGTH(VECTOR_ELT(x, 8))) > n) n = nlen[8];
-
 
798
    if(n > 0) {
-
 
799
	for(i = 3; i < 6; i++)
-
 
800
	    if(nlen[i] == 0)
-
 
801
		error("zero length component in non-empty POSIXlt structure");
-
 
802
	if(nlen[8] == 0)
-
 
803
	    error("zero length component in non-empty POSIXlt structure");
-
 
804
    }
-
 
805
    /* coerce fields to integer */
-
 
806
    for(i = 0; i < 6; i++)
-
 
807
	SET_VECTOR_ELT(x, i, coerceVector(VECTOR_ELT(x, i), INTSXP));
-
 
808
    SET_VECTOR_ELT(x, 8, coerceVector(VECTOR_ELT(x, 8), INTSXP));
-
 
809
 
-
 
810
    PROTECT(ans = allocVector(REALSXP, n));
-
 
811
    for(i = 0; i < n; i++) {
-
 
812
	tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
-
 
813
	tm.tm_mday  = INTEGER(VECTOR_ELT(x, 3))[i%nlen[3]];
-
 
814
	tm.tm_mon   = INTEGER(VECTOR_ELT(x, 4))[i%nlen[4]];
-
 
815
	tm.tm_year  = INTEGER(VECTOR_ELT(x, 5))[i%nlen[5]];
-
 
816
	/* mktime ignores tm.tm_wday and tm.tm_yday */
-
 
817
	tm.tm_isdst = 0;
-
 
818
	if(tm.tm_mday == NA_INTEGER || tm.tm_mon == NA_INTEGER || 
-
 
819
	   tm.tm_year == NA_INTEGER || validate_tm(&tm) < 0)
-
 
820
	    REAL(ans)[i] = NA_REAL;
-
 
821
	else REAL(ans)[i] = mktime00(&tm)/86400;
-
 
822
    }
-
 
823
 
-
 
824
    PROTECT(class = allocVector(STRSXP, 1));
-
 
825
    SET_STRING_ELT(class, 0, mkChar("Date"));
-
 
826
    classgets(ans, class);
-
 
827
    UNPROTECT(2);
-
 
828
    return ans;
-
 
829
}