Hej jag behöver räkna ut vad det blir för datum t.ex 10 arbetsdagar framåt från dagen datum. "Arbetsdagar" är ju ett lite luddigt begrepp som kan variera från land till land (och arbetsgivare till arbetsgivare). Tack för svaret Hej! Intressant att man kan använda Linq på detta sätt Hej! Hej Räkna ut antal dagar från ett datum.
Jobbar i VB 2010 express.
Någon sitter inne med lite tips
TobbeSv: Räkna ut antal dagar från ett datum.
Ett sätt att hantera det på är att skriva en sätt att ta fram alla arbetsfria dagar och se ifall några sådana inträffar i perioden mellan dagens datum och 14 dagar framåt:
Imports System.Linq
Public Sub ExampleUsage()
Dim minimumperiod = 14
Dim currentDate = New DateTime(2014, 4, 15)
Dim holidaysInThisAndNextYear = GetHolidays(currentDate.Year).Union(GetHolidays(currentDate.Year + 1)).ToList()
Dim nextDate = GetNextWorkDateAfterPeriod(currentDate, minimumperiod, holidaysInThisAndNextYear)
MessageBox.Show(nextDate)
End Sub
Private Function GetNextWorkDateAfterPeriod(startdate As DateTime, minimumPeriodLength As Integer, holidays As List(Of DateTime)) As DateTime
Dim holidaysInPeriod = 0
Dim nextWorkDate = startdate.AddDays(minimumPeriodLength + holidaysInPeriod)
' We can't end up on a saturday or sunday, so immediately skip forward to the next monday
If nextWorkDate.DayOfWeek = DayOfWeek.Saturday Then
nextWorkDate.AddDays(2)
ElseIf nextWorkDate.DayOfWeek = DayOfWeek.Sunday Then
nextWorkDate.AddDays(1)
End If
' Find any mo-fr holidays within the considered period
holidaysInPeriod = holidays.Where(
Function(d As DateTime)
Return d.DayOfWeek <> DayOfWeek.Sunday AndAlso d.DayOfWeek <> DayOfWeek.Saturday AndAlso startdate < d AndAlso nextWorkDate >= d
End Function).Count
' Extend the period and see if we encounter any new such holidays
If (holidaysInPeriod > 0) Then
Return GetNextWorkDateAfterPeriod(nextWorkDate, holidaysInPeriod, holidays)
End If
Return nextWorkDate
End Function
Private Function GetHolidays(year As Integer) As List(Of DateTime)
Dim result As New List(Of DateTime)
result.Add(New DateTime(year, 1, 1)) ' New year's day
result.Add(New DateTime(year, 1, 5)) ' Twelfth night
Dim easterSunday = GetEaster(year)
result.Add(easterSunday.AddDays(-2)) ' Good Friday
result.Add(easterSunday.AddDays(-1)) ' Easter Saturday
result.Add(easterSunday) ' Easter Sunday
result.Add(easterSunday.AddDays(1)) ' Easter Monday
result.Add(New DateTime(year, 5, 1)) ' Labor day
' TODO: Add any other holidays, such as midsummer and so on.
result.Add(New DateTime(year, 12, 31)) ' New year's eve
Return result
End Function
' http://en.wikipedia.org/wiki/Computus
Private Function GetEaster(year As Integer) As DateTime
Dim k, m, s, a, d, r, og, sz, oe As Integer
k = year \ 100 ' Secular number
m = 15 + (3 * k + 3) \ 4 - (8 * k + 13) \ 25 ' Secular Moon shift
s = 2 - (3 * k + 3) \ 4 ' Secular sun shift
a = year Mod 19 ' Moon parameter
d = (19 * a + m) Mod 30 ' Seed for 1st full Moon in spring
r = d \ 29 + (d \ 28 - d \ 29) * (a \ 11) ' Calendarian correction quantity
og = 21 + d - r ' Easter limit
sz = 7 - (year + year \ 4 + s) Mod 7 ' 1st sunday in March
oe = 7 - (og - sz) Mod 7 ' Distance Easter sunday from Easter limit in days
Return New DateTime(year, 3, 1).AddDays(og + oe - 1) ' Result: Easter sunday
End Function
Sv:Räkna ut antal dagar från ett datum.
Jag förstår inte så mycket av detta men ska jag lägga detta i en modul och anropa från form via en knapp eller textbox.
typ en textbox med dagen datum och en där resultatet visas?
Jag är inte så bra på detta med funktioner än.
TobbeSv: Räkna ut antal dagar från ett datum.
ExampleUsage()
Men räknar fortfarande med lördag och söndag + en dag.
TobbeSv:Räkna ut antal dagar från ett datum.
Tror att jag fått med både lör sön samt lite fler helgdagar
Finns säkert smartare sätt
Imports System.Linq
Public Class Form1
Public Sub ExampleUsage()
Dim minimumperiod As Integer = 14
Dim currentDate As Date = New DateTime(2014, 4, 15)
Dim weekendscountInPeriod As Integer = 0
' currentDate = InDate.Text
' minimumperiod = Dagar.Text
Dim holidaysInThisAndNextYear = GetHolidays(currentDate.Year).Union(GetHolidays(currentDate.Year + 1)).ToList()
Dim WeekendsInThisAndNextYear = GetWeekends(currentDate.Year).Union(GetWeekends(currentDate.Year + 1)).ToList()
Dim nextDate = GetNextWorkDateAfterPeriod(currentDate, minimumperiod, holidaysInThisAndNextYear, WeekendsInThisAndNextYear)
MessageBox.Show(nextDate)
End Sub
Private Function GetNextWorkDateAfterPeriod(startdate As DateTime, minimumPeriodLength As Integer, holidays As List(Of DateTime), weekends As List(Of DateTime)) As DateTime
Dim holidaysInPeriod As Integer = 0
Dim WeekendCount As Integer = 0
Dim nextWorkDate As Date = startdate.AddDays(minimumPeriodLength + holidaysInPeriod)
' We can't end up on a saturday or sunday, so immediately skip forward to the next monday
If nextWorkDate.DayOfWeek = DayOfWeek.Saturday Then
nextWorkDate.AddDays(2)
ElseIf nextWorkDate.DayOfWeek = DayOfWeek.Sunday Then
nextWorkDate.AddDays(1)
End If
' Find any mo-fr holidays within the considered period
holidaysInPeriod = holidays.Where(
Function(d As DateTime)
Return d.DayOfWeek <> DayOfWeek.Sunday AndAlso d.DayOfWeek <> DayOfWeek.Saturday AndAlso startdate < d AndAlso nextWorkDate >= d
End Function).Count
' Find any sat-sun within the considered period
WeekendCount = weekends.Where(
Function(d As DateTime)
Return d.DayOfWeek <> DayOfWeek.Monday AndAlso d.DayOfWeek <> DayOfWeek.Tuesday _
AndAlso d.DayOfWeek <> DayOfWeek.Wednesday AndAlso d.DayOfWeek <> DayOfWeek.Thursday _
AndAlso d.DayOfWeek <> DayOfWeek.Friday AndAlso startdate < d AndAlso nextWorkDate >= d
End Function).Count
holidaysInPeriod = holidaysInPeriod + WeekendCount
' Extend the period and see if we encounter any new such holidays
If (holidaysInPeriod > 0) Then
Return GetNextWorkDateAfterPeriod(nextWorkDate, holidaysInPeriod, holidays, weekends)
End If
Return nextWorkDate
End Function
Private Function GetHolidays(year As Integer) As List(Of DateTime)
Dim result As New List(Of DateTime)
result.Add(New DateTime(year, 1, 1)) ' New year's day
result.Add(New DateTime(year, 1, 5)) ' Twelfth night
Dim easterSunday As Date = GetEaster(year)
result.Add(easterSunday.AddDays(-2)) ' Good Friday
result.Add(easterSunday.AddDays(-1)) ' Easter Saturday
result.Add(easterSunday) ' Easter Sunday
result.Add(easterSunday.AddDays(1)) ' Easter Monday
result.Add(New DateTime(year, 5, 1)) ' Labor day
' TODO: Add any other holidays, such as midsummer and so on.
result.Add(easterSunday.AddDays(39)) ' kristi flygare
result.Add(New DateTime(year, 6, 10)) ' nationaldagen
Dim midsommarafton As Date = year.ToString + "-06-20"
midsommarafton = midsommarafton.AddDays(5 - midsommarafton.DayOfWeek)
result.Add(New DateTime(midsommarafton.Year, 6, midsommarafton.Day)) ' midsommarafton
result.Add(New DateTime(year, 12, 24)) ' Julafton
result.Add(New DateTime(year, 12, 25)) ' Juldagen
result.Add(New DateTime(year, 12, 26)) ' Annandag jul
result.Add(New DateTime(year, 12, 31)) ' New year's eve
Return result
End Function
Private Function GetWeekends(year As Integer) As List(Of DateTime)
Dim result As New List(Of DateTime)
Dim inx As Integer = 0
Dim CurrDate As New DateTime(year, 1, 1)
For inx = 1 To 365
If CurrDate.DayOfWeek = DayOfWeek.Saturday Or CurrDate.DayOfWeek = DayOfWeek.Sunday Then
result.Add(CurrDate)
End If
CurrDate = CurrDate.AddDays(1)
Next
Return result
End Function
Private Function GetEaster(year As Integer) As DateTime
Dim k, m, s, a, d, r, og, sz, oe As Integer
k = year \ 100 ' Secular number
m = 15 + (3 * k + 3) \ 4 - (8 * k + 13) \ 25 ' Secular Moon shift
s = 2 - (3 * k + 3) \ 4 ' Secular sun shift
a = year Mod 19 ' Moon parameter
d = (19 * a + m) Mod 30 ' Seed for 1st full Moon in spring
r = d \ 29 + (d \ 28 - d \ 29) * (a \ 11) ' Calendarian correction quantity
og = 21 + d - r ' Easter limit
sz = 7 - (year + year \ 4 + s) Mod 7 ' 1st sunday in March
oe = 7 - (og - sz) Mod 7 ' Distance Easter sunday from Easter limit in days
Return New DateTime(year, 3, 1).AddDays(og + oe - 1) ' Result: Easter sunday
End Function
Sv: Räkna ut antal dagar från ett datum.
Detta funkar säkert jätte bra, men jag kan inte fatta hur?
Jag anropar ExampleUsage() från frmHead och ser resultatet i en msgbox men det stämmer inte saknas massa dagar vad gör jag för fel
TobbeSv:Räkna ut antal dagar från ett datum.
Dim minimumperiod As Integer = 14
Dim currentDate As Date = New DateTime(2014, 4, 15)
hur vill du att det skall fungera
I exemplet utgår man från 2014-04-15
och 14 dagar framåt
Det här får du ändra och istället hämta från ex en textruta
vad får du för slutdatum när du kör exemplet?Sv: Räkna ut antal dagar från ett datum.
Fick det att funka bara man tittar lite på koden.
Stort tack till er båda.
Tobbe