Hey all, i have the following code to populate a dropdown to coinside with a companies 2008-2010 calander year. This is the output:
2008 Period 1: 11/30/2008 - 12/27/2008
2008 Period 2: 12/28/2008 - 1/24/2009
2009 Period 3: 1/25/2009 - 2/21/2009
2009 Period 4: 2/22/2009 - 3/21/2009
2009 Period 5: 3/22/2009 - 4/18/2009
2009 Period 6: 4/19/2009 - 5/16/2009
2009 Period 7: 5/17/2009 - 6/13/2009
2009 Period 8: 6/14/2009 - 7/11/2009
2009 Period 9: 7/12/2009 - 8/8/2009
2009 Period 10: 8/9/2009 - 9/5/2009
2009 Period 11: 9/6/2009 - 10/3/2009
2009 Period 12: 10/4/2009 - 10/31/2009
2009 Period 13: 11/1/2009 - 11/28/2009
2009 Period 1: 11/29/2009 - 12/26/2009
2009 Period 2: 12/27/2009 - 1/23/2010
2010 Period 3: 1/24/2010 - 2/20/2010
2010 Period 4: 2/21/2010 - 3/20/2010
2010 Period 5: 3/21/2010 - 4/17/2010
2010 Period 6: 4/18/2010 - 5/15/2010
2010 Period 7: 5/16/2010 - 6/12/2010
2010 Period 8: 6/13/2010 - 7/10/2010
2010 Period 9: 7/11/2010 - 8/7/2010
2010 Period 10: 8/8/2010 - 9/4/2010
2010 Period 11: 9/5/2010 - 10/2/2010
and here is the code for it:
Dim dt2009Start As DateTime
Dim dtTempStart, dtTempEnd As DateTime
Dim dtTempNow As DateTime
Dim nTemp As Integer
Dim itemPeriod As ListItem
Dim timesAround As Integer
dt2009Start = Convert.ToDateTime("11/30/2008")
dtTempStart = dt2009Start
dtTempEnd = dtTempStart.AddDays(27)
ddlInvoicePeriods.Items.Clear()
dtTempNow = DateTime.Now()
nTemp = 1
timesAround = 0
While (dtTempNow > dtTempEnd)
If nTemp = 12 Then
If timesAround = 0 Then
'dtTempStart = Convert.ToDateTime("10/25/2009")
'dtTempEnd = Convert.ToDateTime("11/18/2009")
End If
ElseIf nTemp = 14 Then
If timesAround = 0 Then
dtTempStart = Convert.ToDateTime("11/29/2009")
dtTempEnd = Convert.ToDateTime("12/26/2009")
nTemp = 1
timesAround += 1
End If
End If
itemPeriod = New ListItem()
itemPeriod.Text = dtTempStart.Date.Year.ToString() & " Period " & nTemp.ToString() & ": " & dtTempStart.Date.ToShortDateString() & " - " & dtTempEnd.Date.ToShortDateString()
itemPeriod.Value = dtTempStart.Date.ToShortDateString() & "-" & dtTempEnd.Date.ToShortDateString()
ddlInvoicePeriods.Items.Add(itemPeriod)
itemPeriod = Nothing
Debug.Print(dtTempStart.Date.Year.ToString() & " Period " & nTemp.ToString() & ": " & dtTempStart.Date.ToShortDateString() & " - " & dtTempEnd.Date.ToShortDateString())
dtTempStart = dtTempEnd.AddDays(1)
dtTempEnd = dtTempStart.AddDays(27)
nTemp += 1
End While
If nTemp = 12 Then
dtTempStart = Convert.ToDateTime("12/27/2009")
dtTempEnd = Convert.ToDateTime("11/18/2009")
ElseIf nTemp = 13 Then
dtTempStart = Convert.ToDateTime("11/19/2009")
dtTempEnd = Convert.ToDateTime("12/16/2009")
End If
itemPeriod = New ListItem
itemPeriod.Text = dtTempStart.Date.Year.ToString() & " Period " & nTemp.ToString() & ": " & dtTempStart.Date.ToShortDateString() & " - " & dtTempEnd.Date.ToShortDateString()
itemPeriod.Value = dtTempStart.Date.ToShortDateString() & "-" & dtTempEnd.Date.ToShortDateString()
ddlInvoicePeriods.Items.Add(itemPeriod)
itemPeriod = Nothing
As you may have noticed, the output only goes to 2010 (10/2/2010) which should go all the way to 12/31/2011.
Problem being:
It should start out like so:
2008 Period 13: Nov 30 - Dec 27
2009 Period 1: Dec 28 - Jan 24
2009 Period 2: Jan 25 - Feb 21
2009 Period 3: Feb 22 - Mar 21
...
2009 Period 13: Nov 29 - Dec 26
2010 Period 1: Dec 27 - Jan 23
2010 Period 2: Jan 24 - Feb 20
..
2010 Period 13: Nov 28 - Dec 25
2011 Period 1: Dec 26 - Jan 22
2011 Period 2: Jan 23 - Feb 19
...etc
Any help would be awesome as i am at my end of trying to figure out what i am doing wrong! :o)
David
There is a lot I would change (including using Iain's class for representing the period), and recognizing that nTemp needs to start at 13 for this example and the list is stopping because the loop was told to break at DateTime.Now for no apparent reason, eventhough you said it should continue to run to the end of 2011. But here is how to make the code you posted work:
Dim dt2009Start As DateTime
Dim dtTempStart, dtTempEnd As DateTime
Dim dtTempNow As DateTime
Dim nTemp As Integer
Dim itemPeriod As ListItem
Dim timesAround As Integer
Dim dtReallyEnd As DateTime
Dim year As Integer
year = 2008
dt2009Start = Convert.ToDateTime("11/30/2008")
dtTempStart = dt2009Start
dtTempEnd = dtTempStart.AddDays(27)
dtReallyEnd = Convert.ToDateTime("12/31/2011")
dtTempNow = DateTime.Now()
nTemp = 13
timesAround = 0
While (dtReallyEnd > dtTempEnd)
If nTemp = 14 Then
nTemp = 1
timesAround += 1
year += 1
End If
itemPeriod = New ListItem()
itemPeriod.text = year.ToString() & " Period " & nTemp.ToString() & ": " & dtTempStart.Date.ToShortDateString() & " - " & dtTempEnd.Date.ToShortDateString()
itemPeriod.value = dtTempStart.Date.ToShortDateString() & "-" & dtTempEnd.Date.ToShortDateString()
ddlInvoicePeriods.Items.Add(itemPeriod)
itemPeriod = Nothing
Debug.Print(dtTempStart.Date.Year.ToString() & " Period " & nTemp.ToString() & ": " & dtTempStart.Date.ToShortDateString() & " - " & dtTempEnd.Date.ToShortDateString())
dtTempStart = dtTempEnd.AddDays(1)
dtTempEnd = dtTempStart.AddDays(27)
nTemp += 1
End While
If nTemp = 14 Then
nTemp = 1
timesAround += 1
year += 1
End If
itemPeriod = New ListItem
itemPeriod.text = dtTempStart.Date.Year.ToString() & " Period " & nTemp.ToString() & ": " & dtTempStart.Date.ToShortDateString() & " - " & dtTempEnd.Date.ToShortDateString()
itemPeriod.value = dtTempStart.Date.ToShortDateString() & "-" & dtTempEnd.Date.ToShortDateString()
ddlInvoicePeriods.Items.Add(itemPeriod)
itemPeriod = Nothing
I would still probably make the end date more dynamic (so you don't have to change code in the future when you want more Periods to show) and the start date might be dynamic as well (to keep the list at a manageable length).
As you may have noticed, the output
only goes to 2010 (10/2/2010) which
should go all the way to 12/31/2011.
It stops when dtTempNow > dtTempEnd is no longer True. Plus, you might be interesting in String.Format
It should start out like so:
2008 Period 13: Nov 30 - Dec 27
Why? You set nTemp to 1 at the start, why should it start at 13?
I would create an object to hold your data, similar to this
Public Class Period
Public Property Period As Integer
Public Property StartOfPeriod As Date
Public Property EndOfPeriod As Date
End Class
Then for each iteration of the While loop I would enter the values as list(of Period), once your code has process, use a linq query to sort the data use Period and Date, then bind the list to the drop down.
Hope this helps
Related
I have seven years of temperature data recorded every hour for about 9 weeks.
However two of the years have recorded every half an hour.
For those two years, I only want to use every other line, hence hourly data.
I have 112 nests over the seven years. There are 188550 rows of data...
The first few lines of original data:
> head(TempData)
# A tibble: 6 x 6
Beach Nest Year Datetime Temp NestID
<chr> <dbl> <dbl> <dttm> <dbl> <fct>
1 LB 1 2014 2014-01-12 09:00:00 27.2 LB1_2014
2 LB 1 2014 2014-01-12 10:00:00 27.2 LB1_2014
3 LB 1 2014 2014-01-12 11:00:00 27.2 LB1_2014
4 LB 1 2014 2014-01-12 12:00:00 27.2 LB1_2014
5 LB 1 2014 2014-01-12 13:00:00 27.2 LB1_2014
6 LB 1 2014 2014-01-12 14:00:00 27.1 LB1_2014
Using an if / else statement gives the following warning:
Warning message:In if (.$Year == 2015 | .$Year == 2016) { : the condition has length > 1 and only the first element will be used
So I have tried using an ifelse statement, but now I get an error message:
Error in ifelse(., .$Year == 2015 | .$Year == 2016, subset(row_number()%%2 == : (list) object cannot be coerced to type 'logical'
Can anyone offer any other suggestions/ help?
This the beginning of my code:
FloodedNestsIncSub = group_by (TempData, NestID, Nest, Year) %>%
ifelse (.$Year == 2015 | .$Year == 2016, subset(row_number() %% 2 == 1) ) %>%
mutate(TempDrop = Temp - lag(Temp, n=1, default = first(Temp))) %>%
mutate(Flooded = TempDrop < -0.45)
If I add a comma after "subset(row_number() %% 2 == 1", and leave it blank - the else is simply to go to the next line,
I get a different error:
Error in ifelse(., .$Year == 2015 | .$Year == 2016, subset(row_number()%%2 == :
unused argument (alist())
I need code for
If the year is 2015 or 2016, skip every other row, then go to the next line of code;
else, just go to the next line of code ...
If measurements are every 30 minutes you can just filter the once at 30 minutes out.
This will remove half.
This can be done like this:
TempData %>%
# Only keep whole hours
dplyr::filter(lubridate::minute(Datetime) == 0) %>%
# Rest of pipe
dplyr::mutate(
TempDrop = Temp - dplyr::lag(Temp, n=1, default = first(Temp)),
Flooded = TempDrop < -0.45
)
I have a data frame (dates) that looks like this:
year month start end
2000 06 01 10
2000 06 11 20
2000 06 21 30
I want to create a vector of character strings (one for each row in the data frame) so that each date follows this format:
year month start-end (first row would be 2000 06 01-10).
I've tried using a for loop with the paste function:
titles <- character()
for (i in 1:nrow(dates)){
titles[i] <- paste(dates[i, 1], dates[i,2], dates[i,3], dates[i,4])
}
> titles
[1] "2000 06 01 10" "2000 06 11 20" "2000 06 21 30"
but I can't figure out how to replace the last space with a dash. Is there a way to coerce the paste function into doing this or is there another function I can use?
Thanks for the help
Following your solution, if you just replace
paste(dates[i, 1], dates[i,2], dates[i,3], dates[i,4])
with
paste(dates[i, 1], dates[i,2], paste(dates[i,3], dates[i,4], sep = "-"))
that should work already. This just nests the "-" separating paste within the " " separating paste (default of paste is " ").
A more elegant one-liner would be to use apply:
apply(dates, 1, function(row)paste(row[1], row[2], paste(row[3], row[4], sep = "-")))
[1] "2000 06 01-10" "2000 06 11-20" "2000 06 21-30"
Instead of a loop, you may want to consider:
df$titles <- with(df, paste(year, month, start, end, sep = "-"))
df
# year month start end titles
# 1 2000 06 01 10 2000-06-01-10
# 2 2000 06 11 20 2000-06-11-20
# 3 2000 06 21 30 2000-06-21-30
We can use unite from tidyr:
library(tidyverse)
df %>%
unite("new_date", year:end, sep = " ") %>%
mutate(new_date = sub("\\s(\\d+)$", "-\\1", new_date))
or with two unite's:
df %>%
unite("temp_date", year:start, sep = " ") %>%
unite("new_date", temp_date, end, sep = "-")
Output:
new_date
1 2000 6 1-10
2 2000 6 11-20
3 2000 6 21-30
I have this string that is a date called strRDate and another string called strColor.
The cutoff date is this weeks Monday.
I would like to be something like this:
'// strRDate format is MM/DD/YYYY
Dim strRDate,strColor
strRDate="1/1/1999"
strColor="none"
If strRDate is this weeks Monday or older then <-- HOW DO I DO THIS ???
strColor="green"
else
strColor="red"
end if
So anything older then Oct 21, 2013 would be green, else it would be red.
' for successful parsing of mm/dd/yyyy dates (1033 is EN_US)
Response.LCID = 1033
Dim strRDate, strColor
strRDate = "10/21/2013"
strColor = GetColor(ParseDate(strRDate))
and a few helper functions:
Function GetColor(d)
GetColor = "none"
If IsDate(d) Then
If d <= GetMondayForWeek(Now()) Then
GetColor = "green"
Else
GetColor = "red"
End If
End If
End Function
Function ParseDate(strDate)
ParseDate = vbEmpty
If IsDate(strDate) Then
ParseDate = CDate(strDate)
End If
End Function
Function GetMondayForWeek(d)
' midnight
GetMondayForWeek = CDate(Fix(d))
While Weekday(GetMondayForWeek) <> vbMonday
GetMondayForWeek = GetMondayForWeek - 1
Wend
End Function
I'd probably do the calculation like this:
strRDate = "1/1/1999"
strColor = "none"
monday = Date - (Weekday(Date, vbMonday) - 1)
If CDate(strRDate) <= monday Then
strColor="green"
Else
strColor="red"
End If
Weekday(Date, vbMonday) returns a value between 1 and 7 for each day of the week, with Monday being the first day:
Monday → 1
Tuesday → 2
Wednesday → 3
Thursday → 4
Friday → 5
Saturday → 6
Sunday → 7
Subtract 1 from the return value of the function and you get the difference in days between the current date and the most recent Monday. Subtracting that difference from the current date gives you the date of the most recent Monday, which you can then compare to your input date (use the CDate function to convert the string to an actual date).
This date's monday can be calculated by substracting the Weekday() and adjusting for the Weekday of mondays:
WScript.Echo "german locate (dd.mm.yyyy):"
Dim dtCur : dtCur = #10/10/2013#
Do Until dtCur > #10/24/2013#
Dim dtThisMonday : dtThisMonday = DateAdd("d", -WeekDay(dtCur) + 2, dtCur)
Dim isAfterThisMonday : isAfterThisMonday = dtCur > dtThisMonday
WScript.Echo dtCur, WeekDay(dtCur), WeekdayName(WeekDay(dtCur), True), dtThisMonday, CStr(isAfterThisMonday)
dtCur = DateAdd("d", 1, dtCur)
Loop
output:
german locate (dd.mm.yyyy):
10.10.2013 5 Thu 07.10.2013 True
11.10.2013 6 Fri 07.10.2013 True
12.10.2013 7 Sat 07.10.2013 True
13.10.2013 1 Sun 14.10.2013 False
14.10.2013 2 Mon 14.10.2013 False
15.10.2013 3 Tue 14.10.2013 True
16.10.2013 4 Wed 14.10.2013 True
17.10.2013 5 Thu 14.10.2013 True
18.10.2013 6 Fri 14.10.2013 True
19.10.2013 7 Sat 14.10.2013 True
20.10.2013 1 Sun 21.10.2013 False
21.10.2013 2 Mon 21.10.2013 False
22.10.2013 3 Tue 21.10.2013 True
23.10.2013 4 Wed 21.10.2013 True
24.10.2013 5 Thu 21.10.2013 True
I have a list of dates, which are in this format: YYYY-MM-DD
I would like to be able to sort them in descending order by year (2013, 2012, 2011), and then ascending order by month (January, February, March,...). So what I'm looking for is:
2013-01-01
2013-02-01
2013-03-01
2013-04-01
2013-05-01
2012-01-01
2012-02-01
2012-03-01
...
2012-12-01
2011-01-01
2011-02-01
2011-03-01
...
2011-12-01
Note, the list for the current year would be incomplete until December, so that's why it only goes to 2013-05-01. Previous years would be complete from January-December.
I did a bubble-sort similar to this:
For i = 0 to Ubound(dateArray)
For j = i + 1 to Ubound(dateArray)
if dateArray(i) > dateArray(j) then
tempDate = dateArray(i)
dateArray(i) = dateArray(j)
dateArray(j) = tempDate
end if
Next
Next
but that gives me a list that looks like this:
2011-01-01
2011-02-01
2011-03-01
...
2011-12-01
2012-01-01
2012-02-01
2012-03-01
...
2012-12-01
2013-01-01
2013-02-01
2013-03-01
2013-04-01
2013-05-01
Close, but not quite.
You need to sort ascending when the year is the same in both dates, and descending when the year is different:
Sub SwapValues(ByRef a, ByRef b)
buf = a : a = b : b = buf
End Sub
...
If Year(dateArray(i)) = Year(dateArray(j)) Then
If dateArray(i) > dateArray(j) Then
SwapValues dateArray(i), dateArray(j)
End If
Else
If dateArray(i) < dateArray(j) Then
SwapValues dateArray(i), dateArray(j)
End If
End If
I added a procedure for swapping the values to simplify the code a little.
I've seen this one before... I think this is how I solved it.
For i = 0 to Ubound(dateArray)
For j = i + 1 to Ubound(dateArray)
if (year(dateArray(i)) < year(dateArray(j))) or (year(dateArray(i)) = year(dateArray(j)) and month(dateArray(i)) > month(dateArray(j)))then
tempDate = dateArray(i)
dateArray(i) = dateArray(j)
dateArray(j) = tempDate
end if
Next
Next
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Find the day of a week in R
I have a data for days like 11-01-2011 etc. But I want to add the data corresponding
the date as Monday, Tuesday etc. Is there any R package that contains the information of the dates with days?
weekdays(as.Date('16-08-2012','%d-%m-%Y'))
[1] "Thursday"
The lubridate package is great for this sort of stuff.
> wday(as.Date('16-08-2012','%d-%m-%Y'))
[1] 5
> wday(as.Date('16-08-2012','%d-%m-%Y'), label=TRUE)
[1] Thurs
Levels: Sun < Mon < Tues < Wed < Thurs < Fri < Sat
> wday(as.Date('16-08-2012','%d-%m-%Y'), label=TRUE, abbr = FALSE)
[1] Thursday
Levels: Sunday < Monday < Tuesday < Wednesday < Thursday < Friday < Saturday
Here is some information to create your own library or routine
Constants:
day_of_month
the day of the month
e.g. if input mm-dd-yyy then dd
month:
march = 1
april = 2
may = 3
...
year
yy[yy] (last to digits from yyyy)
*subtract 1 if month jan or feb
e.g. if input date is 02-01-2012 (mm-dd-yyyy)
year = (12-1) = 11
century
[yy]yy (first two digits from yyyy)
e.g. if input year is 2012 then 20 = century
* year 2000, 1900, ... are 20-1, 19-1 respectively
ALGORITHM
step1: floor(century / 4)
step2: year
step3: floor(year/4)
step4: floor(month*2.6 -0.2) #this is the leap year correction
step5: day_of_month
step6: add step1...step5
step7: divide by 7 # modulo 7 in codespeak
step8: the remainder is the day of the week
To Interpret Results:
Sun = 0, Mon = 1, Tues = 3, etc..
Not a library, but as the public service jingle goes...
"Read: The More you Know"
Ref: http://www.faqs.org/faqs/sci-math-faq/dayWeek/